Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use flexbox to achieve a complex, responsive HTML layout?

I have looked into Flexbox to achieve a responsive layout like pictured below. Unfortunately I still have not figured out how to achieve a desktop layout like Figure 1 which rearranges itself to Figure 2 on viewports smaller than 414 pixel.

Figure 1 (desktop viewports)

Desktop version of the layout

Figure 2 (mobile viewports)

Mobile (less than 414px wide) version of the layout (scaled version)

Click here for image in original size

My code so far :

.flexbox {
  display: -webkit-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  flex-wrap: wrap;
  width: 100%;
  margin: 0;
  flex-direction: row;
}
.content-flexbox.one {
  flex-basis: calc(66% - 1rem);
  order: 2;
}
.content-flexbox.two {
  flex-basis: calc(30% - 1rem);
  order: 1;
}
.content-flexbox.three {
  order: 3;
}
.content-flexbox.four {
  order: 4;
}
.content-flexbox {
  margin: 1rem;
  -webkit-box-flex: 1;
  -webkit-flex: 1;
  -ms-flex: 1;
  flex: 1;
}
@media only screen and (max-width: 959px) {
  .flexbox {
    -flex-direction: column;
    padding-top: 1rem;
  }
  .content-flexbox {
    margin: 1rem;
    flex: 1;
    flex-basis: 100%;
  }
  .content-flexbox.one {
    flex-basis: 100%;
    order: 1;
  }
  .content-flexbox.two {
    flex-basis: 100%;
    order: 2;
  }
}
<div class="flexbox">
  <div class="content-flexbox one">
    <h1 class="posttitle">Lorem ipsum</h1>
    <h2 class="subtitle">dolor sit amet</h2>
  </div>
  <div class="content-flexbox two">
    <img src="http://placehold.it/300x300" />
  </div>
  <div class="content-flexbox three">
    <span>Lorem ipsum dolor</span>
  </div>
  <div id="container-voting" class="content-flexbox four">
    <div class="inner-container set">
      <span>Lorem ipsum dolor</span>
    </div>
    <div class="inner-container get">
      <span>Lorem ipsum dolor</span>
    </div>
  </div>
</div>

My question

Is this even possible with flexbox? Is there a better alternative more suited for this layout?

like image 372
Marco Avatar asked Feb 23 '16 10:02

Marco


People also ask

Does flexbox make website responsive?

Flexbox is a relatively new front-end feature that makes building a website layout (and making it responsive!) much, much easier than it used to be. In days past, to build a website, you would have to use float grids or even tables to make your layout look like it should.

Can you use flexbox in HTML?

You can apply Flexbox styling to any HTML element, which means that you can easily restyle and reflow elements independently of each other as there is no fixed container hierarchy like there is in tables.

How do you make a responsive website with Flexbox?

Use flexbox to create a responsive image gallery that varies between four, two or full-width images, depending on screen size: Resize the browser window to see the responsive effect. Use flexbox to create a responsive website, containing a flexible navigation bar and flexible content: With a flexible layout.

What is Flexbox layout (flexible box)?

The Flexbox Layout (Flexible Box) module ( a W3C Candidate Recommendation as of October 2017) aims at providing a more efficient way to lay out, align and distribute space among items in a container, even when their size is unknown and/or dynamic (thus the word "flex").

What is the purpose of the custom Flexbox in the CSS?

Flexbox is just a styling mechanism, which means that you can add and remove it at will, and because you change the flow direction easily, it's almost trivial to go from a horizontal layout of a large display to a vertical layout just by switching the flex-direction.

What is the HTML flexbox and how do you get started?

What Is the HTML Flexbox and How Do You Get Started Using It? CSS hasn't changed much since CSS 3 was released, but the relatively new Flexbox module provides some much needed relief when it comes to creating complex structured layouts in HTML. Flexbox can be considered a much more capable successor to HTML tables.


2 Answers

You’re looking for the experimental grid syntax. Flexbox is good for smaller, widget or component layout systems. Grid is for overall page layout, and it’s awesome.

Thing is, grid is only supported in IE, Edge, and the upcoming Safari browsers right now, but Firefox and Chrome support is allegedly just around the corner, and you can start trying it out today by enabling the right developer flag in those browsers.

Here is some sample code, but again, it will only work if your browser supports the new grid syntax.

*{
  box-sizing: border-box;
}

.flexbox{
  width: 320px;
  display: grid;
  grid-template-columns: calc(50% - 0.5ch) calc(50% - 0.5ch);
  grid-gap: 1ch;
}

.one{
  order: 2;
  background-color: red;
}

.two{
  grid-column: 1 / 3;
  order: 1;
  background-color: green;
}

.three{
  order: 3;
  background-color: pink;
}

.four{
  display: grid;
  grid-column: 1 / 3;
  grid-gap: 1ch;
  order: 4;
  background-color: lavender;
}

.inner-container{
  background-color: violet;
}

@media screen and (min-width: 500px){
  .flexbox{
    width: 500px;
    grid-template-columns: calc(33.333% - 0.333ch) calc(33.333% - 0.333ch) calc(33.333% - 0.333ch);
  }
  
  .one{
    grid-row: 1 / 3;
    order: 1;
  }
  
  .two{
    order: 2;
    grid-column: 2 / 4;
  }
  
  .three{
    order: 3;
  }
  
  .four{
    grid-column: 3 / 4;
    order: 4;
  }
}
<div class="flexbox">
<div class="content-flexbox one">
    <h1 class="posttitle">Lorem ipsum</h1>
    <h2 class="subtitle">dolor sit amet</h2>
</div>
<div class="content-flexbox two">
    <img src="http://placehold.it/300x300" />
</div>
<div class="content-flexbox three">
    <span>Lorem ipsum dolor</span>
</div>
<div id="container-voting" class="content-flexbox four">
    <div class="inner-container set">
        <span>Lorem ipsum dolor</span>
    </div>
    <div class="inner-container get">
        <span>Lorem ipsum dolor</span>
    </div>
</div>
like image 127
Ragdoll Avatar answered Sep 25 '22 00:09

Ragdoll


Although this question explicitly asked for a flexbox approach, there is another way to achive it using simple floats.
A media query allows to rearange the elements in the desired order on viewports less than 414px wide:

.wrap {
  background: #d0d0d0;
  padding: 1%;
}
.wrap:after {
  content: '';
  display: block;
  clear: both;
}
.el {
  float: left;
  margin: 1%;
}
.el1 {
  width: 31.33%;
  padding-bottom: 31.33%;
  background: #FF7676;
}
.el2 {
  float: right;
  width: 64.66%;
  padding-bottom: 14.66%;
  background: #C2FF76;
}
.el3 {
  width: 31.33%;
  padding-bottom: 14.66%;
  background: #FF9BF7;
}
.el4 {
  width: 31.33%;
  padding-bottom: 6.33%;
  background: #9BA4FF;
}
@media (max-width: 414px) {
  .el2, .el4 {
    width: 98%;
    padding-bottom: 31.33%;
  }
  .el1, .el3 {
    width: 48%;
    padding-bottom: 48%;
  }
}
<div class="wrap">
  <div class="el el2"></div>
  <div class="el el1"></div>
  <div class="el el3"></div>
  <div class="el el4"></div>
  <div class="el el4"></div>
</div>

Note that I used padding-bottom to keep the aspect ratio of the elements in this example (more info in this answer).
I don't know what content you intend to put in the blocks but you will need to use absolute positionnig for it if you want to stick with the "padding technique". For plain text content, you can check this fiddle.

like image 44
web-tiki Avatar answered Sep 24 '22 00:09

web-tiki