CSS Grid with Anonymous Children

I’m trying to make a simple navigation sidebar. I want it to be made of several divs so I can switch them out depending on certain situations, and also to highlight the whole cell on mouse over. I also want to use “anonymous” spans (is that the proper term here?) that don’t have explicit CSS for each span, as I’ve seen done in examples like this: https://stackoverflow.com/questions/44092529/make-grid-container-fill-columns-not-rows

I thought grid would be a perfect use for this but I can’t seem to get it to work properly. Here is my codepen: https://codepen.io/FrostyJack/pen/NZMYGj

The spans that make up my sidebar-menu-item are not sizing to the row height I set in the sidebar css (grid-template-rows: 50px;), nor are they obeying the horizontal spacing I set up (grid-template-columns: 20% 30% 40% auto;). Also, if I have no content in any of the spans, they don’t seem to render at all.

I’m not sure I get the layout you are trying to achieve.

But you have grid settings on the .sidebar-menu-item without actually setting it to display: grid

Here’s a wireframe of the layout https://imgur.com/a/xN3Vj4j

I guess I was under the impression that children take on the display settings of their parents. So since my body is set to display: grid, everything on the page should also be grid unless I specifically set them to something else. Is that not correct?

Not only direct children of the grid container will be grid items.

Try using the fr unit instead of %

.sidebar-menu-item {
  display: grid;
  grid-auto-flow: column;
  /*grid-template-columns: 20% 30% 40% auto;*/
  grid-template-columns: 1fr 2fr 3fr auto;
  /* height: 10vh; */
}

I added display:grid; to both .sidebar and .sidebar-menu-item, and it works a lot better. But I’m still confused. What do you mean by “direct children”?

If I have a setup like this:

<body>
    <div class="sidebar">
    </div>
</body>

Isn’t that div a direct child of body?

Yes, .sidebar is a grid item but the spans inside .sidebar-menu-item are not grid items because you are not setting display: grid on it.

.sidebar-menu-item {
  /* this doesn't work unless this element is a grid container */
  grid-auto-flow: column;
  grid-template-columns: 20% 30% 40% auto;
  /* height: 10vh; */
}

Ok. Sorry I am so slow in understanding this.

Why do I have to use display:grid in the children in my example, but it doesn’t seem to need to be done here: https://codepen.io/FrostyJack/pen/ZdoogO

The example you posted only has one grid container and the rest of the elements are direct children, so they are all grid items.

Maybe you are confusing what a grid item is and what grid styles can be applied to a grid item vs a grid container.

You have to make .sidebar-menu-item a grid container for the spans inside it to be grid items. You can not set grid-template-columns on it unless it is a grid container.

Is this not (kind of) what you want?
https://codepen.io/anon/pen/VJxdLd

Yes that’s definitely it. So if an element is a child of a grid element, but the child has grid-template-columns, then that child is no longer a direct child, and I must use display:grid again?

I have changed the code here https://codepen.io/FrostyJack/pen/LKmmXz It is a lot closer to what I want, however the bg colors are not filling the entire cell, they only cover the content.

Also, the spans still don’t render if they have no content, which is a problem as the first and third columns will be used for spacing and will always be empty. I suppose I could use the &nbsp; trick, but that seems a bit hacky.

I also don’t want the last row to stretch vertically to fill the container. I want all rows to be fixed at 50px height.

The problem I am thinking ahead about is that I don’t know how many rows will be in the sidebar, it will change dynamically depending on what else is going on in the app. Sometimes there might only be 4 rows in the sidebar, sometimes 10, sometimes a different number. However, I am not sure, maybe I should start a new thread asking about those problems?

No grid items can just not act as grid containers, because they are not. Making something a grid item does not give it the ability to make columns and rows, only making it a grid container (display: grid) will do that.

I will have to come back to you later to help with the layout. I can say, if you need grid items to act as spacers you can just use non-relative unites (px, rem, etc.) like you often also do for grid-gap.

I’ll probably just start another thread. “Always be iterating!”

Thanks for all your help!