Adaptive Layouts with CSS Grid

With an unlimited amount of screen sizes and browser customizations, it’s important to implement and test your layout using CSS Grid and Media Queries.

Project

Feel free to use your own designs and apply your own styling. You can also use my Figma design if you wish to follow exactly what I have. You can access all the React files.

CSS Grid

CSS Grid allows you to divide your layout in columns and rows. Just like with Flexbox, you can stack your layout elements in a powerful and flexible way, but Grid gives you more power over both columns and rows.

11.03.01_Adaptive_Layouts_with_CSS_Grid-CSS_Grid

Header Component

Let’s edit the Header component and make that into a persistent navigation bar. The existing component has a bunch of inline style that makes the code very disorganized. Let’s delete all the code between the parentheses and start with an empty div tag.

// components/header.js

const Header = ({ siteTitle }) => (
  <div>Header</div>
)

Import Header Component

Let’s bring back the Header component to index layout, right above the Hero div.

// layouts/index.js
<Header />

Once you save, you’ll see an empty bar at the top with the word Header.

Screen_20Shot_202018-07-16_20at_2012.18.52_20PM

Header Content

Our Header needs a logo, a bunch of links and a button. Note that we’re using the Link component to allow us navigate between each links faster and with preloading. Of course, you can also use the normal a tag.

We’re also giving the container div a class name Header so that we can styled the whole thing later. Additionally, we want to have a HeaderGroup to position it adaptively.

<div className="Header">
  <div className="HeaderGroup">
    <Link to="/"><img width="30" /></Link>
    <Link to="/courses">Courses</Link>
    <Link to="/downloads">Downloads</Link>
    <Link to="/workshops">Workshops</Link>
    <Link to="/buy"><button>Buy</button></Link>
  </div>
</div>

Local images

In order to use local images that compile with your React site, you need to use this syntax. Write this code between the first Link tag, replacing the img tag.

<img width="30" src={require('../images/logo-designcode.svg')} />

Another way to write it, which is optional, is to import the asset first.

import logo from '../images/logo-designcode.svg';

<img src={logo} width="30" />

I prefer the first, shorter way because I don’t have to write so many imports when dealing with multiple images.

Online images

For online images, it’s as simple as giving the full address.

<img src="https://link.to/your/image.jpg" />

Header CSS File

Let’s create a stylesheet for your Header component. Right-click the components folder and select New File. Type Header.css. Type this line to import the newly created CSS.

// header.js

import './Header.css'

Header CSS

The Header will allow us to position everything neatly while giving us the flexibility to use a black background later, for readability.

.Header {
    position: fixed;
    width: 100%;
    padding: 50px 0;
    z-index: 100;
}

We use a z-index of 100 to ensure that it’ll always stay on top of fixed or absolute elements if new ones come into play.

FIXED POSITION

We’re also making the Header float on top of the page by setting the position property to fixed.

11.03.02_Adaptive_Layouts_with_CSS_Grid-Fixed_Position

HeaderGroup CSS

Let’s start using the CSS Grid to divide the elements inside our Header div. To start using it, you must set the display property to grid. Secondly, because we’re using 5 columns, we’re setting the grid-template-columns.

.HeaderGroup {
    max-width: 800px;
    margin: 0 auto;
    text-align: center;
    display: grid;
    grid-template-columns: repeat(5, auto);
    align-items: center;
    justify-items: center;
}

REPEAT

When you have repeating elements, you can use the repeat function. This is the equivalent as writing the following:

grid-template-columns: auto auto auto auto auto;

AUTO

Auto means that Grid will distribute the available spacing evenly. So, if one button has a really long text, it will just naturally take more spacing. The negative spacing between the elements will remain consistent.

11.03.03_Adaptive_Layouts_with_CSS_Grid-Auto

ALIGN ITEMS

When having columns or rows, it’s important to be able to align each item horizontally or vertically. Use align-items to vertically align and justify-items to horizontally align. In this case, we just want our items to vertically align in the center.

11.03.04_Adaptive_Layouts_with_CSS_Grid-Align_Items

MAX-WIDTH

This little trick makes sure that your Header never exceeds 800px. If less, it will simply take the whole width.

Links CSS

.Header a {
    color: white;
    font-weight: 700;
}

Header Button CSS

The outline none fixes an issue where there is a glow when clicked on a button.

.Header button {
    padding: 8px 20px;
    font-size: 20px;
    background: #56CCF2;
    border-radius: 10px;
    border: none;
    font-weight: 700;
    outline: none;
    cursor: pointer;
}

Media Queries

Using Media Queries, we can make our layout adaptive based on the screen width. For example, we can hide the third link when the browser width is less than 640px.

@media (max-width: 640px) {
    .Header {
        padding: 15px 0;
    }

    .HeaderGroup {
        grid-template-columns: repeat(4, auto);
    }

    .Header a:nth-child(4) {
        display: none;
    }
}

CSS

In the index.css inside the layouts folder, let’s apply the styling.

@media (max-width: 640px) {
  .HeroGroup {
    padding: 100px 20px;
  }

  .Hero h1 {
    font-size: 40px;
  }

  .Hero p {
    font-size: 24px;
  }
}

Conclusion

We learned some basic CSS Grid and Media Queries techniques. A little later, we’ll play more with the Grid layout as we face new problems.