Search code examples
htmlcss-gridsemantic-markup

Is it possible to completely freely roam / place my DOM elements with CSS grid?


Premise

One of the beautiful aspects of CSS Grid, is the ability to place your DOM elements freely on the grid like this:

<body>
    <nav>navigation</nav>
    <main>main content</main>
    <aside>sidebar</aside>
    <footer>footer</footer>
</main>
body { 
    display: grid;
    grid-template-columns: 7fr 1fr;
    grid-auto-rows: 100px;
    grid-gap: 10px;
    grid-template-areas:  "nav      nav"
                          "content  sidebar"
                          "meta     sidebar"
                          "footer   footer";
}

nav { grid-area: nav; }
main { grid-area: content; }
aside { grid-area: sidebar; }
footer { grid-area: footer; }

Problem

So far so good. But what if I had an element inside a root element which I'd like to place on the grid:

<body>
    <nav>navigation</nav>
    <main>
        <h1>content</h1>
        <!-- New! -->
        <article>some data</article>
    </main>
    <aside>sidebar</aside>
    <footer>copyright 2020</footer>
</main>
article { grid-area: meta; }

That doesn't work. The article does not go into the meta grid area. I want to build semantically correct DOM structures, which in my real life case has me put elements inside other nested elements. But I want to freely roam them on the page, depending on the visual presentation (or even responsiveness).

Is this achievable?


Solution

  • No, you need to declare grid content ahead of time. Grid layout is designed to be for content that is 'fixed' in this regard. If you want to have different content be in the grid for different layouts/screen sizes, use media queries to define new grid layouts at those resolutions.

    From the W3C spec abstract at the beginning of the document:

    This CSS module defines a two-dimensional grid-based layout system, optimized for user interface design. In the grid layout model, the children of a grid container can be positioned into arbitrary slots in a predefined flexible or fixed-size layout grid.

    (emphasis mine)

    The key here is a "predefined" layout grid. You can insert content into a grid dynamically so long as you have thought ahead of time to provide an empty grid track, row, cell, etc. for that content. Otherwise, you're out of luck.