Rebuilding the Leading Design grid

Last year when I worked at Clearleft, I built the website for Leading Design Conference. On the speaker’s page, there is a grid for listing the speakers:

Leading design speaker grid

The speaker grid for Leading Design Conference 2016

It looks great, but I used a hacky combination of floats and margins to build the layout. The perfect approach would have been to use CSS Grid, had it not been behind a feature flag. I've since re-built it in codepen making use of CSS Grid. The original version uses Flexbox and nth-child, and now I've added CSS Grid. I think it’s a good example of the different use cases for Flexbox and CSS Grid, and how they can work together.

Speaker cards

Each speaker card is built using flexbox:


.Card {
    display: flex;
}
.Card-primary {
    display: flex;
    flex-basis: 50%;
    flex-direction: column;
    justify-content: space-between;
}
.Card-secondary {
    flex-basis: 50%;
}

The parent element (Card) has display: flex; applied to it, so that Card-primary (blue container) and Card-secondary (the image) are aligned horizontally, which is the default layout for flex children.

Speaker card

Speaker card on Leading Design Conf 2016 website

.Card-primary (the blue container) is also a flex container so I can wrap the speaker name and title vertically. Flex children wrap horizontally by default, so I had to specify flex-direction: column; to make them wrap vertically.

The grid layout

First of all, I defined the grid and some tracks.


.Grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(155px, 1fr));
}

When display: grid; is applied to the container, all its direct children become grid items (it works the same way as flex parents and children). By default, display: grid; creates one column, so we need to create additional columns (tracks). We can set columns using the grid-template-columns property. In the example above, I’ve used the incredible one line of CSS (explained in my Intro to CSS Grid post), which creates a responsive grid with 4 columns. Each column has a minimum width of 155px and max width of 1fr, so it resizes along with the width of the viewport.

Define positions for each card on the grid:


.Grid {
   display: grid;
   grid-template-columns: repeat(4, minmax(155px, 1fr));
}
.Grid-item {
   grid-column: 2 / 4;
}
.Grid-item:nth-child(3n+2) {
   grid-column: 1 / 3;    
}
.Grid-item:nth-child(5n+3), 
.Grid-item:nth-child(7n+5) {
   grid-column: 3 / 5;
}

Two things are happening here:

  • grid-column property defines specific tracks on the grid. So, grid-column: 1 / 3; means the card's position will start on track 1 and end on track 3.
  • nth-child decides which style declarations are applied to each card. So, if the card is in position 5, 8, 11, etc, it'll get grid-column: 1 / 3; applied to it. This creates a little bit of randomisation around where cards end up on the grid. So every time the content manager adds a new speaker to the website (via the CMS), they don’t know where it’ll end up—it’s fun!

Finally, I wrapped this code in a feature query, to make sure that only browsers which support CSS Grid attempt to render it.


@supports (display: grid) {
...
}

Those that don't will use the slightly simpler layout using flexbox, which is declared outside the feature query. Flexbox is so well supported now, it can be used as a fallback for CSS Grid—how awesome is that?

Here's the codepen example:

See the Pen Leading Design grid. Flexbox fallback and @supports for CSS Grid styles by Lottejackson (@lottejackson) on CodePen.