Open benface opened 5 years ago
a different amount of pixels has been added to each link because they have different default widths, which results in unequal gaps
Are you mostly trying to work around having a responsive but uniform "padding" between items? If this is the case, "maxing" flex grow, which keys off a fraction of the empty space in the flex direction and the content size of the item, might not be the way to go, because short of that max, the grow will still be related to the unique size of content in each item?
Even if min()
/max()
hasn't landed everywhere yet, I think your best bet with currently specified behavior would be to use them in ways like adding padding: 10px max(10px, 3%)
on your flex items. Though I know the 3%
or whatever amount of %
/vw
would have to be related to the amount of flex items.
Are you mostly trying to work around having a responsive but uniform "padding" between items?
Yes.
If this is the case, "maxing" flex grow, which keys off a fraction of the empty space in the flex direction and the content size of the item, might not be the way to go, because short of that max, the grow will still be related to the unique size of content in each item?
Hmm, but if the value of flex-grow
is the same for all items (e.g. 1
), it is uniform. That is, if there are 4 items and the flex container gets wider by 4 pixels, each item grows by 1 pixel, which is the behaviour I want. Unless I'm misunderstanding what you're saying?
Even if min()/max() hasn't landed everywhere yet, I think your best bet with currently specified behavior would be to use them in ways like adding padding: 10px max(10px, 3%) on your flex items.
Yes, that would probably be a better solution than any of the "possible solutions" I tried above, thank you. Even better would be max(10px, min(3%, 30px))
(or clamp(10px, 3%, 30px)
), but it's still not ideal:
flex-grow
makes the items grow as soon as there's available space (filling the container short of the max), whereas to get the same behaviour with padding
, you would need to fine-tune the 3%
value very precisely based on the total width + minimum padding of the flex items, and if you get it slightly wrong it could cause unwanted overflow / wrapping.
Growing the padding
instead of the content's width doesn't affect my use case so much, but imagine if the flex items were list items (<li>
) instead, and they each contained a link (<a>
), and you didn't want to have any gap between the links like in my example. The padding in the <li>
would make that difficult / impossible.
I have an alternate solution for you: https://codepen.io/TabAtkins/pen/OKNPgE
The gist of it is that the nav is a grid, and each item is placed across three rows: minmax(10px, 40px) auto minmax(10px, 40px)
. The auto
column will size to the item's width, then the "side" columns will grow from 10px to 40px, depending on available space, all at the same rate.
You do have to predict how many items you'll have, but that's it.
@tabatkins Ok, yeah, that is a great solution! A bit annoying to have to use Grid for something that really sounds like it should be handled by Flexbox, but I'm OK with that solution if nobody feels like flex-max-grow
would be a worthy addition.
Wait, I spoke too soon! It looks like the gaps between the texts are not equal in your pen. Not sure why.
As far as @tabatkins grid demo goes, you must add white-space: nowrap;
to the nav
for equal spacing. Otherwise very long items will have less space around them.
Update The 10px
min argument in the demo is mostly useless. To get the effect that @benface wants, you must put the 10px
on something like the padding of the grid items.
@jonjohnjohnson Instead of using white-space
to increase the min-content contribution to equal the max-content one, I would replace auto
with max-content
in the grid template.
And yes, minmax(10px, 40px)
is not that useful because of grid-column: span 3
. With sibling-index()
we could use something like grid-column: calc(3 * sibling-index() - 1)
Problem
Look at this Codepen: https://codepen.io/benface/pen/EqPxwB
If there's enough horizontal space, I would like the links to grow in width but only up to a certain amount (40 more pixels). So on a mobile device they would stay the same, but on a large screen they would be slightly wider, like this:
Possible solutions
.link { flex-grow: 1; }
.link { flex-grow: 1; } .flex { max-width: 450px; margin: 0 auto; }
.link { flex-grow: 0.1; }
.link { flex-grow: 1; max-width: 90px; }
max-width
, a different amount of pixels has been added to each link because they have different default widths, which results in unequal gaps:@media (min-width: 450px) { .link { padding: 10px 30px; } }
Proposed solution
A new
flex-max-grow
(ormax-flex-grow
, or evenflex-grow-max
?) property that defines how much a flex item is allowed to grow: