Dynamic image layout using CSS Grid

In this example we will create a CSS grid (without JavaScript) that can automatically adapt its width or height depending on how many items we have in the grid.

This layout can also be achieved with Flexbox, but it can be tricky and time consuming. It’s also difficult to change the gaps (gutters) between the grid items. With CSS Grid, grid gaps can be changed with ease depending on your project and can be the perfect way to create a grid in CSS.

Why would we need to do this? Imagine you had a grid of three items and you need to remove one. Maybe one is removed because it’s managed in a CMS or the data you have is always changing. Whatever it may be, it can look a bit messy and usually ends up looking like this:

Grid example

Flexbox can solve this scenario, but what if your grid is more complex and the items in your grid are listed across multiple rows with varying heights? Flexbox can solve this to an extent but not quite as fluidly and adaptively as what we can do here.

Here’s an example of our grid, you can hit the delete button to remove an item from the grid:

See the Pen Adaptive Grid by Chris (@chrismorrison) on CodePen.

How does it work?

.item {
  &:first-child:nth-last-child(6) ~ .item {
    &:nth-of-type(2) {
      color: red;
    }
  }
}

.item selects all items.

&:first-child:nth-last-child(6) ~ .item calculates when there are 6 items in the list.

&:nth-of-type(2) selects the specific element in the list.

The combinator

The ~ combinator (general sibling combinator) is used to select only siblings which follow the first element.

Example: p ~ span will match all elements that follow a <p>.

This is basically the opposite of the + combinator (adjacent sibling combinator), which will select elements which are previous to the first element.