CSS Grid: Learning new layout

I’ve been writing base layouts for CSS a long time. Come next month, I’m going to be using a new feature to do that work for the first time in many years, CSS Grid. Yes, flexbox came along and I used it for some pieces of the layout, but it didn’t change the way I laid out entire pages. Next month that’s changing.

CSS Grid is landing in Chrome and Firefox after years of tireless work by specification authors, developers who gave feedback, and browser implementers. I’ve been spending time lately diving into the basics of CSS Grid, seeing how it works, figuring out the pain points it can solve easily for me along with seeing the new ways in which I can make sites better through writing clearer, more maintainable CSS

I’ll be exploring CSS Grid in a small series of posts trying to get some answers to questions and problems I’ve had working on the web over the years. I want to see how I can combine CSS Grid with the other layout options in ways that enable us to achieve some layouts (such as centering text in a block) that should be easier than they’ve been in the past.

.grid > * {
    display: inline-block;
    float: left;
    width: 50%;
    margin: 0;
    padding: 0;
}
.grid > *:nth-of-type(2n+1) {
    clear: left;
}
.grid > *:nth-of-type(2n+1):last-child {
    margin-left: 25%;
}

@media( min-width: 27.5em ) {
    .grid > * {
        width: 33.333333334%;
    }
    .grid > *:nth-of-type(2n+1) {
        clear: none;
    }
    .grid > *:nth-of-type(2n+1):last-child {
        margin-left: 0;
    }
    .grid > *:nth-of-type(3n+1) {
        clear: left;
    }
    .grid > *:nth-of-type(3n+1):last-child {
        margin-left: 33.333333334%;
    }
    .grid > *:nth-of-type(3n+1):nth-last-child(2) {
        margin-left: 16.666665%;
    }
}


@media( min-width: 40em ) {
    .grid > * {
        width: 25%;
    }
    .grid > *:nth-of-type(3n+1) {
        clear: none;
    }
    .grid > *:nth-of-type(3n+1):last-child,
    .grid > *:nth-of-type(3n+1):nth-last-child(2) {
        margin-left: 0;
    }
    .grid > *:nth-of-type(4n+1) {
        clear: left;
    }
    .grid > *:nth-of-type(4n+1):last-child {
        margin-left: 37.5%;
    }
    .grid > *:nth-of-type(4n+1):nth-last-child(2) {
        margin-left: 25%;
    }
    .grid > *:nth-of-type(4n+1):nth-last-child(3) {
        margin-left: 12.5%;
    }
}

@media( min-width: 50em ) {
    .grid > * {
        width: 20%;
    }
    .grid > *:nth-of-type(4n+1) {
        clear: none;
    }
    .grid > *:nth-of-type(4n+1):last-child,
    .grid > *:nth-of-type(4n+1):nth-last-child(2),
    .grid > *:nth-of-type(4n+1):nth-last-child(3) {
        margin-left: 0;
    }
    .grid > *:nth-of-type(5n+1) {
        clear: left;
    }
    .grid > *:nth-of-type(5n+1):last-child {
        margin-left: 40%;
    }
    .grid > *:nth-of-type(5n+1):nth-last-child(2) {
        margin-left: 30%;
    }
    .grid > *:nth-of-type(5n+1):nth-last-child(3) {
        margin-left: 20%;
    }
    .grid > *:nth-of-type(5n+1):nth-last-child(4) {
        margin-left: 10%;
    }
}

@media( min-width: 70em ) {
    .grid:not(.logo-grid) > * {
        width: 16.666666667%;
    }
    .grid:not(.logo-grid) > *:nth-of-type(5n+1) {
        clear: none;
    }
    .grid:not(.logo-grid) > *:nth-of-type(5n+1):last-child,
    .grid:not(.logo-grid) > *:nth-of-type(5n+1):nth-last-child(2),
    .grid:not(.logo-grid) > *:nth-of-type(5n+1):nth-last-child(3),
    .grid:not(.logo-grid) > *:nth-of-type(5n+1):nth-last-child(4) {
        margin-left: 0;
    }
    .grid:not(.logo-grid) > *:nth-of-type(6n+1) {
        clear: left;
    }
    .grid:not(.logo-grid) > *:nth-of-type(6n+1):last-child {
        margin-left: 41.666666667%;
    }
    .grid:not(.logo-grid) > *:nth-of-type(6n+1):nth-last-child(2) {
        margin-left: 33.333333334%;
    }
    .grid:not(.logo-grid) > *:nth-of-type(6n+1):nth-last-child(3) {
        margin-left: 25%;
    }
    .grid:not(.logo-grid) > *:nth-of-type(6n+1):nth-last-child(4) {
        margin-left: 16.7%;
    }
    .grid:not(.logo-grid) > *:nth-of-type(6n+1):nth-last-child(5) {
        margin-left: 8.333333334%;
    }
}

The above code is what we currently use to build the About page grid for our team on this site. I’ve been using this great pattern for years since I learned it from a fellow CSSer I admire a lot, but it’s a pain, all that nth-child float clearing, ugh.

Contrast the above code with what it takes to get the same thing working in CSS Grid:

.grid {
  display: grid;
  grid-gap: 0;
  grid-template-columns: 50% 50%;
  margin: 0;
  padding: 0; 
}

.item {
  align-items: center;
  background-color: green;
  color: white;
  display: flex;
  font-family: Helvetica, sans-serif;
  font-size: 2em;
  height: 200px;
  justify-content: center;
  list-style-type: none;
  margin: 0 0 2em 0;
  padding: 0;
  width: 100%;
}


@media( min-width: 27.5em ) {
  .grid {
    grid-template-columns: 33.333333334% 33.333333334% 33.333333334%;
  }
}

@media( min-width: 40em ) {
  .grid {
    grid-template-columns: 25% 25% 25% 25%;
  }
}

@media( min-width: 50em ) {
  .grid {
    grid-template-columns: 20% 20% 20% 20% 20%;
  }
}

@media( min-width: 70em ) {
  .grid {
    grid-template-columns: 16.666666667% 16.666666667% 16.666666667% 16.666666667% 16.666666667% 16.666666667%;
  }
}

The above code is in a Codepen, so check it out and play around with it. Remember, you still need to use a browser that CSS Grid works in, so Chrome Canary, Firefox Nightly, or turn on the feature flag in Chrome or Firefox. Seeing the results of a well-worn pattern for laying out a list of items change so easily just by changing the grid-template-columns was so exciting.

If you look at the above code, it’s three lines of CSS to have you on your way to making a grid that you can experiment with and explore the possibilities. In addition, you can also move content around fairly easy and let it automatically reflow or you can direct where each piece of content goes in the grid. You can even name your areas and use that to define your grids. There is just so much you can do with this and I’m just getting started myself.

I dug into Rachel Andrew’s Grid by Example and read her latest on 24 Ways to understand what would be supported in the first roll out. Then I read up on @supports to learn how I’d create fallbacks before making some prototypes in Codepen. It took me an afternoon of reading, learning, and thinking and I was completely sold and wanting to dive deeper.

There are some notes of caution around accessibility and how we display content versus the source order HTML, making sure we are careful with how keyboard users navigate the site. That’s what’s next for me: digging into the details and making sure I understand how to implement layout with grid while making sure everyone can still use it easily.

Comments

Contact Us

We'd love to hear from you. Get in touch!

Phone

+1 617-283-2807

Mail

P.O. Box 961436
Boston, MA 02196