How to nest elements using CSS Grid?

Say I have a header with a logo and a heading (h1 tag). Then I have the main body of the page with headings and paragraphs or images (h3, p, img tags), and a footer with whatever. The HTML might be:

<body>
<div class="container">
    <header>
        <h1>My Heading</h1> 
    </header>
    <section>
        <h3>Topic 1</h3>
        <img src="" />
        <p>lotsa words</p>
        <h3>Topic 1</h3>
        <p>lorem ipsum, yeah yeah yeah</p>
    </section>
    <footer>
    </footer>
</div>
</body>

I want a 12-column layout. The header, main section and footer will all span the width of the page. That’s simple enough. I can either do:

.container {
    display: grid;
    grid-template-columns: 12;
    grid-template-rows: 3;
}

or

.container {
    display: grid;
    grid-template-areas: "h h h h h h h h h h h h"
                                     "s s s s s s s s s s s s"
                                     "f f f f f f f f f f f f";
}
header {
    grid-area: h;
}
section {
    grid-area: s;
}
footer {
    grid-area: f;
}

That’s all fine, but say I want the h1 to start at column 3 and span 2 columns. I’ve tried:

h1 {
    grid-column: 3 / 2;
}

and even just:

h1 {
grid-column-start: 3;
}

to just get it to start in column 3.
I’ve also tried:

h1 {
    grid-area: h1;
}

and changed the container’s header row to “h h h1 h1 h h h h h h h” but that doesn’t work, either.
The same problem exists for getting the picture to start at, say, column 5 and span 4 columns, with text to the right spanning two columns. What am I doing wrong?

Each of your elements should be in a <div> with the class you want to use, like

<div class = "h1">
  <h1>My Heading</h1> 
</div>

and

.h1 {
    grid-column: 3 / span 2;
}

Try that. More great info can be found at https://www.w3schools.com/css/css_grid.asp

Here’s an example: https://gridbyexample.com/examples/example21/

Hi! First of all, this:

grid-column: 3 / 2

is shorthand for:

grid-column-start: 3;
grid-column-end: 2;

As Jacey pointed out, when you want to use grid-column or grid-row shorthand properties and specify the span-length, the second value should be span n where n is the number of columns.

The main issue, however, is that your h1 cannot be positioned in the grid since it is not a grid item.

With Grid, just as Flexbox, only direct children of the grid of flex container are grid/flex items. So in your case, your header can be positioned along the grid tracks, but you cannot position the children of your header.

There actually will be a new value for the display property which will allow you to do what you want, but right now it only has about 5% browser support. It’s called display: contents. What this value does is basically ignore the parent container (the header, in this case) and instead, the children of header would become grid items, and you’d be able to position them along the main grid.

Rachel Andrew wrote a wonderful article about display: contents.

For now, if you want to position the items within header, you will have to either make header a flex or grid container and position the items along its own subgrid.

2 Likes

Thanks to all of you for responding.

@JaceyBennett, I was thinking I could use the h1 element as is because it’s block level. Can you tell me why I’d need to put it inside a div?

@mewmew, I think you found my error, that the h1 isn’t a direct child of the container. Thanks for your explanation and for the info on the new contents value.

@elisecode247, that’s a very helpful website. I’d seen that example but wasn’t able to apply it to my case (because I was making the error that mewmew caught).