Can I make this flex-box direction using 1 flex container and 4 flex items
----- ----- -----
| 1 | | | | |
----- | 3 | | 4 |
----- | | | |
| 2 | | | | |
----- ----- -----
Can I make this flex-box direction using 1 flex container and 4 flex items
----- ----- -----
| 1 | | | | |
----- | 3 | | 4 |
----- | | | |
| 2 | | | | |
----- ----- -----
Using a container around 1
and 2
you can do it, like this:
* {
box-sizing: border-box;
}
.wrapper {
display: flex;
flex-direction: row;
}
.container {
flex-direction: column;
flex-grow: 1;
}
.item {
background: tomato;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
flex-grow: 1;
border: 1px solid black;
}
.inner {
height: 100px;
line-height: 100px;
}
.outer {
height: 200px;
line-height: 200px;
}
<div class="wrapper">
<div class="container">
<div class="item inner">1</div>
<div class="item inner">2</div>
</div>
<div class="item outer">3</div>
<div class="item outer">4</div>
</div>
But if you don't want to use a container for 1
and 2
I'm afraid you can not do it, because the direction of the children is determined by the parent.
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
Your best shot is to use the property align-self
, this allows the default alignment (or the one specified by align-items) to be overridden for individual flex items. like this:
* {
box-sizing: border-box;
}
.wrapper {
display: flex;
flex-direction: row;
}
.item {
background: tomato;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
flex-grow: 1;
border: 1px solid black;
}
.inner {
height: 100px;
line-height: 100px;
}
.outer {
height: 200px;
line-height: 200px;
}
.item-top{
align-self: flex-start;
}
.item-bottom{
align-self: flex-end;
}
<div class="wrapper">
<div class="item inner item-top">1</div>
<div class="item inner item-bottom">2</div>
<div class="item outer">3</div>
<div class="item outer">4</div>
</div>
But note that float, clear and vertical-align have no effect on a flex item.
As opposed to the accepted answer, this layout is achievable without using a wrapper container, though this solution requires a fixed height.
The trick is to set the container's flex-direction to column
, which means that:
flex-basis
calculations will happen against the container's height, which we'll use to position the 1st and the 2nd childrenflex-wrap
will wrap the content to the right, which we'll use to position the 3rd and the 4th childrenExample:
.container {
height: 10rem;
width: 30rem;
background: lightgray;
display: flex;
/* by setting the flex-direction to "column" the
items that won't fit into the vertical space
will be wrapped to the right */
flex-direction: column;
flex-wrap: wrap;
}
.child {
box-sizing: border-box;
border: 1px crimson solid;
font-size: 3rem;
}
.child:nth-child(1),
.child:nth-child(2) {
/* because we set the container's flex-direction
to column, the flex-basis will make the children
occupy the vertical space. In our case, because
the 1st and the 2nd children are both 50%, they
fill up the first column completely and push out
the 3rd and the 4th children */
flex: 0 1 50%;
}
.child:nth-child(3),
.child:nth-child(4) {
flex: 0 1 100%;
}
<div class="container">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
</div>