Holy grail layout using CSS Grid

in developer •  7 years ago 

Holy grail layout using CSS Grid

A simple, responsive, mobile first holy grail layout with CSS Grid.

CSS Grid Layout allows us to create layouts using proper grids made up of rows and columns. Working responsively is easy with lots ways to manipulate the grid for different devices. A basic knowledge of HTML and CSS will go a long way here, but CSS Grid is so simple I'd argue anyone could pick this up pretty quickly.

The first step is to create some elements. Grid works on a parent and child basis. The parent is the grid, the children are grid items. So <main> will be our parent, with <header> <article> <aside> and <footer> direct children of that grid. 

<main>
 <header>Header</header>
 <article>Article</article>
 <aside>Aside</aside>
 <footer>Footer</footer>
</main>

It helps to add basic styling to the grid items so we can what's happening when we make changes to our code. 

main > * }
       padding: 1rem;
       font-size: 2rem;
       font-weight: 400;
       color: white;
}

header,
footer {
       background: lightgreen;
}

article {
       background: lightblue;
}

aside {
       background: lightpink;
}

With our grid items now visible, we can work mobile first and create our first layout. As we only need one column on mobile, we only need to define rows. We create the grid by applying display: grid; to our parent container and define rows using grid-template-rows. The header and footer have a fixed height and we split the remainder of the viewport in to two equal rows repeating 50vh (50% of vertical height).

main {
      display: grid;
      grid-template-rows: 6rem repeat(2, 50vh) 6rem;
      max-width: 60rem;
      margin: 0 auto;
}

Our grid items will now be stacked in a single column. We want them to stay this way until the viewport is wide enough to fit multiple columns. We can do this by declaring a minimum width for our holy grail layout using a @media query. You should keep all declarations nested inside the same media query, I have split them out to easily add explanations. 

@media screen and (min-width: 48rem) {
       main {
             grid-template-rows: 6rem 100vh 6rem;
             grid-template-columns: repeat(3, 1fr);
       }
}

This tells the browser that at a minimum width of 48rem (768px) to combine our middle two rows of 50vh in to a single 100vh row, whilst splitting our single column in to 3 columns of equal width using the repeat and fr (fraction) functions.

With the grid defined all we need to do is layout our grid items. If you draw a three column grid, you’ll see it’s made up of 4 vertical lines. This is the basis of the named lines positioning approach which I'm using here.

@media screen and (min-width: 48rem) {

        header,
        footer {
                grid-column-start: 1;
                grid-column-end: 4;
       }

}

To maintain a full width with the new column set up, we start both <header> and <footer> on line 1 and end on line 4. 

@media screen and (min-width: 48rem) {

        article {
                 grid-column-start: 1;
                 grid-column-end: 3;
       }

        aside {
               grid-column-start: 3;
               grid-column-end: 4;
       }

}

To make our two main components to sit side by side in the 100vh row, we tell the <article> to take up 2/3 columns, by starting on line 1 and ending on line 3. The <aside> then takes up the remaining column, starting on line 3 and ending on line 4. All you need to do now is resize your browser to see the two layouts working responsively. 

That's it! 

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!