I'm curious if this layout is possible with flexbox. I can't seem to work out divs 3 & 4 to fall under #2. This is pretty easy with floats, just curious if I'm missing some properties that may help with flexbox.
Layout
+-------+-------+-------+
| div 1 | div 2 |
+ +-------+-------+
| | div 3 | div 4 |
+-------+-------+-------+
Markup
<div class="features">
<div class="feature feature-1">1</div>
<div class="feature feature-2">2</div>
<div class="feature feature-3">3</div>
<div class="feature feature-4">4</div>
</div>
Demo
http://codepen.io/mikevoermans/pen/xbWvJJ?editors=110
Instead of using a float to create layouts by floating elements to the left or the right, flexbox allows you to create layouts by aligning items to a single axis. The axis can be horizontal or vertical. It is best used for distributing space for items in the same axis.
Using floats we are limited to place items left or right but using flexbox we can modify our models in all four directions. Flexbox is a new concept in CSS to achieve a responsive webpage with some important properties of flexbox. We should use flexbox over floats.
The basic difference between CSS Grid Layout and CSS Flexbox Layout is that flexbox was designed for layout in one dimension - either a row or a column. Grid was designed for two-dimensional layout - rows, and columns at the same time.
CSS Flexbox Layout Module Before the Flexbox Layout module, there were four layout modes: Block, for sections in a webpage. Inline, for text. Table, for two-dimensional table data.
Flexbox does not like flex items that expand through multiple columns or rows, because in fact flexbox has no grid notion.
However, using some tricks, you can achieve this layout (and more complicated ones too):
Use a row layout
┌─┬─┬─┬─┐
│1│2│3│4│
└─┴─┴─┴─┘
Allow line breaks with flex-wrap: wrap
.
Use a pseudo element to force a line break after 2
┌─┬─┐
│1│2│
├─┼─┤
│3│4│
└─┴─┘
Use flex: 1
on all flex items.
┌─────────┬─────────┐
│1 │2 │
├─────────┼─────────┤
│3 │4 │
└─────────┴─────────┘
Set margin-left: 50%
to 3
┌─────────┬─────────┐
│1 │2 │
└─────────┼────┬────┤
│3 │4 │
└────┴────┘
Set height: 200px
, to 2, 3 and 4. Set height: 400px
to 1.
┌─────────┬─────────┐
│1 │2 │
│ ├─────────┘
│ │
└─────────┼────┬────┐
│3 │4 │
└────┴────┘
Set margin-bottom: -200px
to 1:
┌─────────┬─────────┐
│1 │2 │
│ ├────┬────┤
│ │3 │4 │
└─────────┴────┴────┘
Since you have borders, use box-sizing: border-box
on all boxes to make height
include the borders. Otherwise 1 would need height: 416px; margin-bottom: -216px
.
Note flexbox introduces auto
as the new initial value of min-width
. That could allow the content to force some boxes to grow. That would break the layout, so disable it with min-width: 0
or setting overflow
to anything but visible
.
Here is the code:
.features {
display: flex;
flex-flow: row wrap;
}
.feature {
background: #ccc;
border: 8px solid #fff;
height: 200px;
box-sizing: border-box;
min-width: 0;
flex: 1;
}
.feature-1 {
/* Make it taller without increasing the height of the flex line */
height: 400px;
margin-bottom: -200px;
}
.features:after {
/* Force line break */
content: '';
width: 100%;
}
.feature-2 ~ .feature {
/* Place 3 and 4 after the line break */
order: 1;
}
.feature-3 {
margin-left: 50%;
}
<div class="features">
<div class="feature feature-1">1</div>
<div class="feature feature-2">2</div>
<div class="feature feature-3">3</div>
<div class="feature feature-4">4</div>
</div>
However, it would be easier to modify the HTML in order to have nested flexboxes.
#wrapper {
height: 400px;
}
.flex {
display: flex;
}
.column {
flex-direction: column;
}
.flex > div {
min-width: 0;
flex: 1;
}
.item {
background: #ccc;
border: 8px solid #fff;
}
<div id="wrapper" class="flex row">
<div class="item">1</div>
<div class="flex column">
<div class="item">2</div>
<div class="flex row">
<div class="item">3</div>
<div class="item">4</div>
</div>
</div>
</div>
Not possible with flexbox, but possible with CSS Grid. It's not yet shipped with all major browsers, but there's a polyfill:
https://jsfiddle.net/hvdq63ah/
.features {
display: grid;
grid-template-areas:
"feature1 feature2 feature2"
"feature1 feature3 feature4";
grid-template-columns: auto minmax(min-content, 1fr) minmax(min-content, 1fr);
grid-template-rows: auto minmax(min-content, 1fr);
background-color: #fff;
}
.feature-1 { grid-area: feature1 }
.feature-2 { grid-area: feature2 }
.feature-3 { grid-area: feature3 }
.feature-4 { grid-area: feature4 }
.feature {
border: 1px solid black;
padding: 20px;
}
<div class="features">
<div class="feature feature-1">1</div>
<div class="feature feature-2">2</div>
<div class="feature feature-3">3</div>
<div class="feature feature-4">4</div>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With