3 column layout where outer columns are the same width with middle taking up rest of space?
This is for a header, I have a logo and logotype on the left, buttons on the right, and I am planning to have a search box in the middle and I want it to be central which does mean that I need left and right to be the same width even though content on one side will have empty space
I can use grid to make all columns the same width but I can't then specify that the middle column should be super wide. Also tried flexbox but that appears to be a dead end. My usual front end person is dealing with stuff so I can't ask her
I've tried:
- grid with 1fr auto 1fr and making the middle column try and be 100%
- flexbox trying to see if I can make the flex basis the same for left and right
- grid with 3 columns that are the same and trying to push middle to be wider
Current solution:
- Duplicate left and right so each side has a copy of both within the same grid cell, but on the left the right clone is opacity 0 and pointer-events none. They will have to grow to the largest https://codepen.io/skylarkx/pen/ZYGMzYE

123 Replies
Will the right side with buttons be dynamic and vary in how many buttons are on the right?
Depending on if a user is logged in or not, but I'm likely only going to have 3 buttons on the right and logo will be longer but at smaller widths the logotype may disappear
I have considered hard coding widths for different screen widths and logged in/out, but I figured there might be a magic solution
Another solution was to duplicate left and right on both sides but hide one and do
pointer-events: none;
Well with grid you can play around with the center column fr amount. You could say I the grid center column takes more fractions of the container.
1fr 4fr 1fr
That doesn't respect the widths of the content
I have been working on similar problem. I did solve it.
Let me look at my code
Auto 1fr auto?
Left and right would be different widths
You can set them on the child if you need
Yeah I used grid and set them to as specific rem value.
Nothing clever I guess. lol
To avoid queries you could use clamp. A balanced column width feature would be nice
have you tried
grid-template-row: 1fr max-content 1fr;
with a width: 100vw;
on the center item ?https://codepen.io/skylarkx/pen/ZYGMzYE this is what I've got so far trying to duplicate the contents but it's not happy with the text and I'm not sure why
I'll try that
It overflows

Also, grid doesn't like the text for some reason
grid-template-columns 3fr 10fr 3fr;
But that doesn't respect the content width
I am not sure what you are meaning by respecting the content width. If I put grid-template-columns 1fr 10fr 1fr; and then increase the button sizes from 2rem to 6rem. Both columns will grow to the same size that fits the button sizes.

Huh
https://codepen.io/skylarkx/pen/zxGJONK do you happen to know why the text is overflowing?

This front end stuff is confusing
do you really need the 2 side column to change width?
can't you have a fixed width ?
Ideally yes, it should be less effort than using magic numbers
not really...
mixxing intrinsic sizing and extrinsic sizing in the same template is pretty hard to do with grid
But if it's as simple as just doing
1fr 20fr 1fr
but making it respect the text I don't have to worry about updating the numbersI'm not even sure if what you are lookin for is actually doab;e
Also, red and blue aren't the same width in that
I was thinking more about something like
200px 1fr 200px
(or whatever the largest side column width is)But I would like the middle to have all of the remaining space
that would do it
I don't get it xD
But the 200px may leave additional gaps
ya you either set a width on both or on the children
or respect the content to set width
you would need to find the value that fits the space your button or icon uses
like if the icon is 150px but the icons need 200px, you set 200px on both
and you can set the button ocntainer width with a custom prop in JS/PHP depending on if the user is loggedin or not
I would like 3 columns, left and right should be the same width and be the widest content of the 2, if left is 176px and right is 155px then they're both 176px, with the centre being the remaining width
My plan was to just duplicate left and right and place them in the same cells so they have to be the same width, it kinda works but grid doesn't seem to care about text https://codepen.io/skylarkx/pen/ZYGMzYE
I don't get why it's ignoring text
it's actually ignoring the image
'cause images are wierd
Huh
So I'll put that in a div and set the div size
should have attrib with width/height xD
Ah
https://codepen.io/skylarkx/pen/ZYGMzYE well that does work
CSS is wild
Thank you all, I'm about to eat but I may have further questions in a bit
I hope what I was trying to achieve is now clear
the fact that you duplicate the buttons will bite you with accessibility
It's aria-hidden
But I can do more if needed
I can use placeholders for the elements. I just want things to be automatic and not have to worry about changes
you know the number of buttons in the template you use to generate your HTML, and you know their width and spacing. you should use that to compute the with (and I would assume the logo would not change size too much if at all)
Cool glad you got a solution. I tend to wrap images in divs in flex and grid containers.
that would be less error prone and more futur proof than duplication markup
I will consider it
you still need the attributes on <img>
Browsers will be wonky with intrinsic values for images
also helps render them faster and change the values in CSS after
same with svg (specially in grid)
Another thing with images is I always set the width and height attributes to match the image aspect ratio. so if it is a square image width="1" height="1"
I typically set them the actual size 😄
or if in a layout and I need that layout shift* to not break I'll put the size I need
really just have something seems to help lol such a oddity imo
Well I handle that in css with width 100% height auto. It will infer the reserved space. Also aspect ratio css for good measure
I so prefer the backend to avoid bodges like that :catSweat:
I’m likely going to hand over this project to a friend once they’re available I just want to give them an idea of what I want for them to do it properly
Well, I am happy with it, although the effect is far less noticeable than I had originally thought
if it's not noticeable it mean it works
At what point is there too much backdrop-filter blur? I'm probably going to change the cards to not use a gradient as it feels like a bit much https://codepen.io/skylarkx/pen/ZYGMzYE
(the website is for my shop on a Minecraft server as I'm stocking 614 chests and players need guidance, the money is of course not real)
look alright
Before and after


(I am getting help from a friend now)
It would be killer if there was CSS property which could define a length like
get-height: card-height;
and then elsewhere can do set-height: card-height;
right now the full width cards have a fixed height but thinking about having a hidden square under it to get it to have the same height
I doubt this would help with the header as otherwise it would depend on itself unless the get-width was the width prior to set-width so you can do get-width: left; set-width: max(left, right);
and get-width: right; set-width: max(left, right);
if you used a grid for the... well grid, you can just set the rows to be
1fr
that way all the rows will be the same size no matter their contentOh that's perfect, thank you
Is there a good way to cut off the last row on a grid? I don't care about how many items there are (it may be completely filled) but it would be nice to always have a filled grid. The row height is flexible so I can't just make the container shorter by a row and have
overflow: hidden
, I also thought that I could just shift the footer up to cover the last row but again I don't know by how much to shift it, I could have the footer be in the grid and set to the last row but that would still leave a gap. So the only option I can think of is have another container which is the same size as the parent with subgrid and then have a footer at the bottom which covers the last row, but that may be overcomplicated but I assume would work
No you can't
Ah
You would need js for that
ty, thank you for saving me hours of trying
Does the number of columns stay consistent?
No
Now to go and find whoever I need to suggest :first-row :nth-row :nth-last-row :last-row and same for column
There would be a way, but it's probably not worth it 😄
I can do it with JavaScript hiding the last however many tiles but it'd be nice if there was a CSS only option just
.card:last-row {display:none}
sortedbut if you did that, would the row before it become the :last-row? 🤣
but yes, some pseudo-things for that would be nice
No, the cards on the last row still exist but are display none, same as if you do
div:first-child {display:none}
It will be possible with style queries someday, but no browser support the part you would need.
Ouh
ah, yeah, i see what you mean. that would be cool
And
style()
accepts a computed style, not a defined style?More likely
scale: 0;
or visibility: none
would be better because of the "is that the last row now?" As pointed by kevinI think tab atkins was talking about something like this when I saw him at css day last year...
For now chromium only support and only for custom props (and IIRC it's behind a flag?)
safari supports it too, its only ff that doesn't
behind a flag in ff
I did catch Kevin's video about it today and it appears that it still needs to be defined, but with CSS variables it's not clear either way
Not clear if you can extract
grid-row: -2/-1
without it being set on the elementsNope
I'm not even sure
.getComputedStyles()
would give it to you, especially if you use an implicit gridYeah
'Cause that would not work in an implicit grid with a style query either BTW
Aha
Ohhh it just clicked, yeah that’s tricky, there may end up needing to be an exception that a row or column selector is selected prior to display but that may be tricky
I found a way that would work with CSS, but it would require covering basically every potential situation, in terms of number of elements, that it's definitely not worth exploring.
Ah, neat that it is possible
Doesn’t work on mobile so can’t take a look rn
I'm in a crunch to make some videos, so I know what I'll be recording tomorrow 🤣
Oh that is cool
It actually breaks for smaller widths, so I went back to my fix of sticking a square under the row
Stylus doesn't support @container nor color-mix, I really should stop using it, I started because a friend used it and it looked so much quicker :catExhausted: SCSS apparently doesn't either
preprocessors can't keep up with css anymore, lol. Sucks, because they still do have use cases, but it can definitely be annoying
Ah
I feel like I know why it works but I can't understand how it works xD
haha, yeah even as I was writing it I was having a hard time wrapping my head around what exactly I was doing 😄
it's a case of :
&:nth-child(an)
: for containers with a multiple a
of children
:nth-last-child(-n + a + 1)
: find the first element that has less than a - 1
following siblings
~ *
: select all children after it
I think...what
sucks that you need the hard coded container queries on the with
trinna decompose your weird selectors xD
yeah, custom props/media/whatever would be nice there
that's were being able to extract a computed style value would be nice xD
tho I have no idea how you would even begin to write a syntax for extracting the number of columns in an implicit grid :/
with the minmax, it's all very predictable, which is why I can hard code it.
something like this maybe ?
The container queries check how many columns, and then the selector finds the last of the row above and then selects all siblings after
yeah but that only works if all the columns are the same width
yeah... though as long as you're using
repeat()
I feel like you could do it, but if you were repeating different sizes, it's just more complex.the cq only checks the container width, the number of columns is infered from that because math
Yeah, but because of the values, they select for the number of columns
BTW @Kevin Powell you might want to add a warning about the viewport being too wide for the example to work, I was trying to understand why nothing worked at first cause the preview defaulted to just above your last queried size
I'll clean it up 👍
https://codepen.io/skylarkx/pen/ZYGMzYE thank you, it's perfect, and it can be tweaked to work with some of the wide tiles I've got (just changing nth-child to nth-of-type and then making the types different)
cleaned it up, commented it up, and added a part that breaks down the selectors a little to try and explain what's happening
missing the article link for
<!-- thanks to this article by Keith Clark setting me down the right path -->
xDhaha, oops
added, thanks. Also made a version looking at getting columns, but it's so much easier 😄 (also linked in the codepen)
his article is only 13 years old 😄
I forgot you can't use custom props in container queries :/
this no worky
I really wish you could.
and we still don't have a
child-count()
do we ?
would have made all that way """easier"""we have
sibling-count()
(in Canary)
I'm guessing you could do something with :has()
to pass it to the parent
actually, I'm not sure we could 🤔
if we have sibling-count()
i dont know why we can't have child-count()
thoughI have been following this thread with interest.
Using style queries has been mentioned and, as I needed an excuse to practice using them following your (Kevins) previous video , I wanted to have a go to achieve a similar result.
Of course, style queries (currently) require custom properties so I had to define a custom property to define the number of columns for each breakpoint. I know that the original doesn't use breakpoints as such but the end result is very similar.
https://codepen.io/cbolson/pen/xbGyONy
so,
sibling-index()
and sibling-count()
would work... as long as you know calculus, anyway - https://codepen.io/t_afif/pen/QwbZKPB
oh, he's also using an if()
in there to then apply the style... (which means latest version of chromium only)