Reputation: 68818
I currently have this simple Flexbox layout:
ul {
display: flex;
flex-wrap: wrap;
list-style: none;
padding: 0;
}
li {
flex-grow: 1;
padding: 20px;
margin: 10px;
background: #ddd;
}
<ul>
<li>lorem</li>
<li>ipsum</li>
<li>dolor</li>
<li>sit</li>
<li>amet</li>
<li>consectetur</li>
<li>adipisicing</li>
<li>elit</li>
<li>sed</li>
<li>do</li>
<li>eiusmod</li>
<li>tempor</li>
<li>incididunt</li>
<li>ut</li>
<li>labore</li>
<li>et</li>
<li>dolore</li>
<li>magna</li>
<li>aliqua</li>
</ul>
I would like my elements to fill the container width (as now), but leave the last line left aligned. As you can see, the last line attempts to fill the space, and this sometimes makes the last elements to get an ugly width.
Does Flexbox allows us to do that ? I can't find a way to do it.
Upvotes: 41
Views: 20871
Reputation: 81
Faced the same problem and solved it with css grid. Last rule of the grid is aligned left and all the elements have the same width.
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
ul {
display: grid;
gap: 10px;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
list-style: none;
padding: 0;
}
li {
padding: 20px;
background: #ddd;
}
<ul>
<li>lorem</li>
<li>ipsum</li>
<li>dolor</li>
<li>sit</li>
<li>amet</li>
<li>consectetur</li>
<li>adipisicing</li>
<li>elit</li>
<li>sed</li>
<li>do</li>
<li>eiusmod</li>
<li>tempor</li>
<li>incididunt</li>
<li>ut</li>
<li>labore</li>
<li>et</li>
<li>dolore</li>
<li>magna</li>
<li>aliqua</li>
</ul>
Upvotes: 6
Reputation: 559
You can also append empty items with height: 0
to the container and make them take up for the extra space: http://codepen.io/anon/pen/OyOqrG
(Source copied from my codepen:
<div class="container">
<p></p>
<p></p>
<p></p>
...
<p class="empty"></p>
<p class="empty"></p>
</div>
.container {
max-width: 490px;
display: flex;
flex-flow: row wrap;
background-color: #00f;
}
.container p {
min-width: 90px;
margin: 5px;
background-color: #f00;
height: 90px;
flex-grow: 1;
}
.container p.empty {
height: 0;
margin-top: 0;
margin-bottom: 0;
}
Upvotes: 9
Reputation: 6796
UPDATE: Turns out I didn't understand correctly, I misread the question as looking to target only the last item in the list, rather than the last line. Will leave the below here, though, for the benefit of anyone who trips over this question in the future and may find it helpful.
If I'm understanding you correctly then, to achieve what you want, you'll need to set the flex-grow
property on all but the last item which you can do by combining the negation pseudo class :not()
with the :last-child
pseudo class, like so:
ul {
display: flex;
flex-wrap: wrap;
list-style: none;
padding: 0;
}
li:not(:last-child) {
flex-grow: 1;
}
li {
padding: 20px;
margin: 10px;
background: #ddd;
}
<ul>
<li>lorem</li>
<li>ipsum</li>
<li>dolor</li>
<li>sit</li>
<li>amet</li>
<li>consectetur</li>
<li>adipisicing</li>
<li>elit</li>
<li>sed</li>
<li>do</li>
<li>eiusmod</li>
<li>tempor</li>
<li>incididunt</li>
<li>ut</li>
<li>labore</li>
<li>et</li>
<li>dolore</li>
<li>magna</li>
<li>aliqua</li>
</ul>
Upvotes: -1
Reputation: 288690
You can add an ::after
pseudo-element with a huge flex-grow
, so that the flex-grow: 1
of the li
elements will be negligible:
ul::after {
content: '';
flex-grow: 1000000000;
}
ul {
display: flex;
flex-wrap: wrap;
list-style: none;
padding: 0;
}
li {
flex-grow: 1;
padding: 20px;
margin: 10px;
background: #ddd;
}
ul::after {
content: '';
flex-grow: 1000000000;
}
<ul>
<li>lorem</li>
<li>ipsum</li>
<li>dolor</li>
<li>sit</li>
<li>amet</li>
<li>consectetur</li>
<li>adipisicing</li>
<li>elit</li>
<li>sed</li>
<li>do</li>
<li>eiusmod</li>
<li>tempor</li>
<li>incididunt</li>
<li>ut</li>
<li>labore</li>
<li>et</li>
<li>dolore</li>
<li>magna</li>
<li>dolore</li>
<li>magna</li>
<li>aliqua</li>
</ul>
Upvotes: 74
Reputation: 1909
You can remove flex-grow: 1
on li and add justify-content: space-between
on ul
ul {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
list-style: none;
padding: 0;
}
li {
padding: 20px;
margin: 10px;
background: #ddd;
}
<ul>
<li>lorem</li>
<li>ipsum</li>
<li>dolor</li>
<li>sit</li>
<li>amet</li>
<li>consectetur</li>
<li>adipisicing</li>
<li>elit</li>
<li>sed</li>
<li>do</li>
<li>eiusmod</li>
<li>tempor</li>
<li>incididunt</li>
<li>ut</li>
<li>labore</li>
<li>et</li>
<li>dolore</li>
<li>magna</li>
<li>aliqua</li>
</ul>
Upvotes: 1
Reputation: 9739
You can set the pseudo ::last-child
. All <li>
grow except last one
CSS
ul {
display: flex;
flex-wrap: wrap;
list-style: none;
padding: 0;
}
li {
flex-grow: 1;
padding: 20px;
margin: 10px;
background: #ddd;
}
li:last-child {
flex-grow: 0;
}
Upvotes: 2