A great method for solving this problem is provided in this answer by @LGSon.
As the answer points out, the key is to give each item flex-grow: 1
.
Here's why it works:
These are the requirements from the question:
- two flex items
- on small screens, they should stack into a column
- on large screens, they should line up in a row 50/50
- if one item has no content, it should consume no space, and the other should consume all space
flex: 1 1 50%
This is the attempted solution in the question:
.div1, .div2 {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 50%;
}
This code won't work because it doesn't meet Requirement #4. Flex items will share available space equally (flex-grow: 1
), after they are each sized to 50% width (flex-basis: 50%
).
Since there is no free space left over when two items are 50/50, flex-grow
has no effect and items will always be 50/50, regardless of content.
Note that the flex-basis
property is, per spec guidelines, rendered first, before any free space is distributed by flex-grow
and flex-shrink
.
.container {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-around;
}
.div1,
.div2 {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 50%;
}
.div1 {
background-color: red;
}
.div2 {
background-color: green;
}
<div class="container" style="width: 250px;">
<div class='div1'>
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</div>
<div class='div2'>
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</div>
</div>
<hr/>
<div class="container" style="width: 1000px;">
<div class='div1'>
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</div>
<div class='div2'>
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</div>
</div>
<hr/>
<div class="container" style="width: 1000px;">
<div class='div1'>
</div>
<div class='div2'>
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</div>
</div>
flex: 1
Using flex: 1
wouldn't work either. This is equivalent to:
flex-grow: 1
flex-shrink: 1
flex-basis: 0
Because flex items are initially sized to flex-basis: 0
, all container space is distributed equally. Again, this violates Requirement #4, as both items will be 50/50, regardless of content.
.container {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-around;
}
.div1,
.div2 {
flex: 1;
}
.div1 {
background-color: red;
}
.div2 {
background-color: green;
}
<div class="container" style="width: 250px;">
<div class='div1'>
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</div>
<div class='div2'>
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</div>
</div>
<hr/>
<div class="container" style="width: 1000px;">
<div class='div1'>
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</div>
<div class='div2'>
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</div>
</div>
<hr/>
<div class="container" style="width: 1000px;">
<div class='div1'>
</div>
<div class='div2'>
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</div>
</div>
flex: auto
This is the only solution that works. It breaks down to:
flex-grow: 1
flex-shrink: 1
flex-basis: auto
This basically says:
- The initial size of each flex item is the size of the content.
- Once that size is determined,
flex-grow
can enter the picture to allot remaining space.
Since the initial size of an item with no content is zero, this allows the second item to occupy all space on the line.
The answer I cited uses flex-grow: 1
instead of flex: auto
. That has the same effect since flex-shrink: 1
and flex-basis: auto
are default values.
.container {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-around;
}
.div1,
.div2 {
flex: auto;
}
.div1 {
background-color: red;
}
.div2 {
background-color: green;
}
<div class="container" style="width: 250px;">
<div class='div1'>
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</div>
<div class='div2'>
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</div>
</div>
<hr/>
<div class="container" style="width: 1000px;">
<div class='div1'>
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</div>
<div class='div2'>
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</div>
</div>
<hr/>
<div class="container" style="width: 1000px;">
<div class='div1'>
</div>
<div class='div2'>
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</div>
</div>
More information