Case study: Check out Rarebird’s brand-new Hydrogen store →

Fully Scalable CSS Grid

paolo_tatone

20 Jul 2018 - Development, Front-End, CSS, Design

Paolo Tatone

3 mins read
Fully Scalable CSS Grid

CSS Grid is a great feature! What I want to share here is a little tweak that should be used when working with grids and scalable contents. In a responsive context, a way to proportionally scale contents is making their dimensions to depend from a percentage of window’s width, using vw units. If we don’t care about the overall grid element dimension (width and height), the enclosed cells could not be proportional, and will stretch over the two dimensions. There is no evidence of the problem with a square grid but it is instead evident with a rectangular one. If your goal is to maintain the internal cells with 1:1 proportion, even when the column and row counts do not match, this is a solution for you. The trick is to calculate the ratio of the grid’s width, given its height (in vw units), number of rows and number of columns.

A South Park example

(Inspired by 4x4pixels)

Kyle is a nice, square, CSS Grid guy… right click on him on the Pen, and turning on the inspector you’ll see it has a 4x4 grid layout..

kyle

See the Pen SouthParkGrid - Step 1 by Paolo Tatone (@aleph1ow) on CodePen.


Also check he shares his dimensions along with his friends Stan and Kenny.

kenny kyle stan

See the Pen SouthParkGrid - Step 2 by Paolo Tatone (@aleph1ow) on CodePen.

I’m big boned!

Ah! There’s also Cartman! …but, wait a second… he should be a bit wider than the others! What happened to him? Did he go on a diet? Let’s turn on the inspector…

See the Pen SouthParkGrid - Step 3 by Paolo Tatone (@aleph1ow) on CodePen.


We can see that all these CSS Grid guys have a 4x4 layout, but Cartman has 6X4. His grid cells are not 1:1. Since the container’s width equals its height, the cells look rectangular because there are more columns than rows in Eric’s body :)

kenny slim-cartman

We are going to introduce a mixin that solves the problem by calculating the width ratio based on the height and the number of columns/rows.

  @mixin scalable-grid($columns, $rows, $height) {

    width: $columns * $height / $rows;

    display: grid;
    grid-gap: 0;
    grid-template-columns: repeat($columns, minmax(1%, 1fr));
    grid-template-rows: repeat($rows, minmax(1%, 1fr));
  }

See the Pen SouthParkGrid - Step 4 by Paolo Tatone (@aleph1ow) on CodePen.


This way the cells’ aspect ratio will always be 1:1.

cartman

Ha-ha! Now I recognize you little bastard!

A close friend of everybody

Of course, this is also valid when there are more rows than columns, like when it’s Christmas and Mr.Hanky 2X6 comes…

fat-mr-hanky

See the Pen SouthParkGrid - Step 5 by Paolo Tatone (@aleph1ow) on CodePen.


Better maintain his proportions with our mixin :D

kenny cartman mr-hanky kyle stan

See the Pen SouthParkGrid - Step 6 by Paolo Tatone (@aleph1ow) on CodePen.


And now you can kill Kenny :)

Usefulness?

Besides this (funny?) example, I found this approach useful in my front-end experience anytime I needed to show images inside a grid — a very complex rectangular grid with some empty cells — but I wanted to keep the aspect ratio of every cell 1:1 (with some of the images spanning over multiple cells), and also get the CSS grid to be fully responsive.