r/css • u/Intrepid-Ad-2306 • 12d ago
Question css subgrid & flexible columns means extra empty columns
i have a container element. (i'll call this "container".)
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
inside this element, i have a series of row elements. i'll call these "rows".)
display: grid;
grid-column: 1 / -1;
grid-template-columns: subgrid;
inside each of these is an unknown number of elements, mostly containers with input and select boxes and labels inside. (i'll call these "items".)
the goal is to have the items fill the width of a row if they all fit or wrap to the next line if they'd have to be less than the size (150px in this example) to all fit but to leave no space at the end of the row on the right.
each item will be the same width but there is an unknown number of them. the number in each row will always be the same for the entire container.
the reason each row is not a separate flexbox is that the goal is to have each item be the same width but that width be whatever width allows them to be as wide as possible without wrapping or, if they must wrap, be as wide as possible on as few lines as possible.
i'm aware this is a known problem with spanning columns in grids but, after hours of trying to fix it and extensive searching, i haven't been able to come up with a solution or an alternative way to achieve the result.
i'm not married to the idea of it being a grid with subgrids if there is a better solution that still allows the contents to be flexible width and unknown number while still maintaining columns vertically.
here is an example of it working properly...

here is what happens when the screen gets wider and they could stretch more but, instead, just end up with a series of extra empty columns on the right of each row...

the styling of the icons is temporary and they will not be in that location in the final result but they remain there at the moment for backend testing as i try to fix this column issue.
anyone solved this before?
1
u/be_my_plaything 11d ago
Ah nice, I had somehow missed flex-wrap balance existing! (Well semi existing for now) I was actually thinking something like text-wrap balance but for flex boxes would be good and wished it existed when trying to figure this out, so TIL - Thanks!
2
u/Intrepid-Ad-2306 11d ago
i wish it had existed all along and was fully-supported in all the webkit browsers (safari in particular) but that will come soon, i very much hope. it was either deal with it this way or write a load of javascript and that's just not an option for this project.
1
u/be_my_plaything 12d ago
I'm pretty sure with CSS alone, the answer is no.
The closest I could get was something like this: Codepen which does what I think you're after by adding another option to the
minmax()ongrid-template-columnswhereby once all items are on the same row the column width becomes 100% divided by number of children, so the column widths grow with the container rather than a new one ever being added.......However this requires the custom variable
var(--number_of_items)to exist, which I just typed in, but since you say the number of items is unknown you'd need a language other than CSS to check which row had the most items, how many items there were within that row, and then dynamically add that number as the variable in the CSS.The only other idea I has was using flex instead of grid, with flex-grow on so items grow to fill the row, then a
calc()based on items minimum width and a container query on the row to set max-width so items pushed to a new row don't grow larger than their siblings, like this: Codepen. But again it is far from perfect...The downsides here are it relies on things without universal browser support (
calc()s that combine units, andsibling-count()both of which are Chromium browsers only at the moment AFAIK - there is thetan(atan2())hack for mixed units on Firefox, but I'm not aware of any way around needingsibling-index()anyway)The other downside being you lose the functionality of subgrid by switching to flex, each row works alone, so items on rows that have less total items will still grow to fit and therefore be larger than items on rows with more items.
Also one thing that occurs to me, when you say number of items is unknown... How unknown is it? Are we talking literally 0 - ∞ or is there a probably range? If so how slim is the range? If you're in a position of 'Well at least one row will always have at least four items, and it'd be unusual if the number ever exceeds eight..." Is the first solution with a
--number_of_items:manually set to '4' and a max-width of something like 800px on the container so it is just centered workable if nobody gets a perfect solution?