Let's say I have a list of users, and each user has some number attached to it. Each user is listed like so:
<span><a href="/user/Niet">Niet</a> ⇒ 2</span>
They are all styled with:
.userlist>span {
display: inline-block;
padding: 2px 6px;
border: 1px solid currentColor;
}
Here's an example of it in action:
Okay, this looks all right, the list of users can get quite long so compact-ness is important here. My issue is that that right edge is horribly inconsistent, so I'm wondering if there's any way to improve that.
My first thought was, of course, just setting a fixed width on the spans. However username widths aren't exactly predictable. You can have someone called iiiii
and someone called WWWWW
but since this isn't a monospace font you get "iiiii" and "WWWWW", very clearly different widths there. So the "max width" would basically be the widest allowed character, which is W
, multiplied by the max username length. Let's try that...
Ew. I might as well use a <ul>
if that's the result I'm going to get. The next thought was maybe something involving display:table
to have the widths be consistent across columns, while still remaining dynamic and - assuming most people have sensible usernames (*cough*... oh hey, so that's how you escape Markdown... huh...) - but it does tend to end up with a lot empty space still.
So my current idea is some kind of justify-alignment. That works quite well for text, right? But alas, text-align: justify
does precisely bugger all in this case, possibly because there are no spaces between the elements to be justified.
My final attempt was using flexbox, something I'm already using to good effect in the site's new design. Let's see how it looks with display: flex; flex-wrap: wrap;
on the container, and flex: 1 0 auto;
on the elements...
Huh, that doesn't look too bad. Not too bad at al-
... Hm. So close. What I'd really like is for the last line of elements to not get flex stretched all the way across. It's okay when there's three or four on the last line, but two looks a bit silly and just one fills the whole width and looks ridiculous.
So I guess this whole little adventure boils down to one simple question:
How can I achieve justify-align-like behaviour, in which elements are spaced to use the full width of the container, except on the last line where they should use their natural width?
To complete this little story, thanks to @Michael_B's answer, here's how I've implemented the solution:
.userlist:after {
content: '';
flex: 10 0 auto;
}
And the result:
Beautiful.
By default items start from the left if flex-direction is row , and from the top if flex-direction is column . You can change this behavior using justify-content to change the horizontal alignment, and align-items to change the vertical alignment.
To align one flex child to the right set it with margin-left: auto; From the flex spec: One use of auto margins in the main axis is to separate flex items into distinct "groups".
To center the inner div element we will make the parent a flex container. By adding the display: flex; property we make the section element a flex container allowing us to adjust the layout of the div which is now a flex item. To center out item horizontally we use the justify-content: center; .
Using flexbox, create 3 or 4 "phantom" items that always occupy the last slots.
So, for instance, user #82 is currently your last entry.
Make fake users 83, 84, 85 with visibility: hidden
.
Alternatively, try just one phantom item at the end with visibility: hidden
and flex-grow: 10
. Target it with :last-child
or :last-of-type
pseudo-class.
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