Reputation: 433
I am struggling to make a simple layout using flexbox.
Layout: two divs.
I've tried this arrangement below but failed. In this example, second block is wrong, then each block should occupy 50% of "one row". I've tried some other variants - all doesn't seem to work.
.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>
Upvotes: 2
Views: 628
Reputation: 87191
I simplified your CSS a little.
Set the container
to display: flex
(and remove flex-wrap: wrap;
or else they won't sit side-by-side on wider screens)
Set flex-grow: 1
, take equal space left based on each items content
Add a media query that when triggered at the requested width, here I used 600px (2 times 300px), changes the flex-direction
to column
,which will make them stack vertical.
Stack snippet
.container {
display: flex;
}
.div1, .div2 {
flex-grow: 1;
}
.div1 {
background-color: red;
}
.div2 {
background-color: green;
}
@media (max-width: 600px) {
.container {
flex-direction: column;
}
}
<div class="container">
<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">
<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>
Updated
If there will be a smaller amount of content in either of the 2 flex items (div1
/div2
), and you still want them to be equal width, change flex-grow: 1
to flex-basis: 100%
.
Doing so they now will always take 100% of the width, but since they can't wrap, the flex-shrink
property will come into play, which defaults to 1
, and does the same as flex-grow
, though will instead shrink the items equally.
Since this will also make the empty div
take the same width, we need to address that, which we easily can do with this rule, where an :empty
div
will be sized to 0%
.div1:empty, .div2:empty {
flex-basis: 0%;
}
Stack snippet
.container {
display: flex;
}
.div1, .div2 {
flex-basis: 100%;
}
.div1:empty, .div2:empty {
flex-basis: 0%;
}
.div1 {
background-color: red;
}
.div2 {
background-color: green;
}
@media (max-width: 400px) {
.container {
flex-direction: column;
}
}
<div class="container">
<div class='div1'>
"Lorem ipsum dolor sit amet."
</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."
</div>
</div>
<hr/>
<div class="container">
<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>
Updated based on a comment
Instead of using media query, one can use flex-wrap
in combination with min-width
, flex-grow
and flex-basis
.
And this work like this, where flex-basis: 50%
is their start value, flex-grow: 1
make them take all available space after they break line, and min-width
make sure they break line when their parent's width becomes smaller than 2 times the min-width
value.
And for the empty div
we now need display: none
instead.
Stack snippet
.container {
display: flex;
flex-wrap: wrap;
}
.div1, .div2 {
flex-grow: 1;
flex-basis: 50%;
min-width: 150px;
}
.div1:empty, .div2:empty {
display: none;
}
.div1 {
background-color: red;
}
.div2 {
background-color: green;
}
<div class="container">
<div class='div1'>
"Lorem ipsum dolor sit amet."
</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."
</div>
</div>
<hr/>
<div class="container">
<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>
Upvotes: 2
Reputation: 370993
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:
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:
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>
Upvotes: 4