The future of class-based CSS grid systems

What does a class-based CSS grid system look like and where could we see it going in the future. Perhaps with CSS variables and the style attribute?

By Luke Whitehouse on

CSS

Article

Last week a friend of mine, Rory, created a proof of concept for a lightweight grid system using CSS variables, weighing in at a crazy 469 bytes (non-gzipped!).

https://twitter.com/roikles/status/837266610218020864

After talking things through with Rory and a couple of my colleagues I really think this concept could be where the future of class-based grid systems will go, no matter if they're using Flexbox, CSS Grids, display: inline-block; or even floats.

http://codepen.io/roikles/pen/dvGOXB/

What is a class-based CSS Grid System?

Before I go any further, I'd better clear things up as buzzwords can be a little confusing. A class-based Grid system is a working title I like to use when a Grid's layout is dictated by the classes you have on it at present, rather than predefined properties that cannot be altered.

To give an example, let's take a basic 4 column grid system:

<div class="grid">
  <div class="grid-item">1</div>
  <div class="grid-item">2</div>	
  <div class="grid-item">3</div>
  <div class="grid-item">4</div>
</div>
.grid {
  margin: 0;
  padding: 0;
}


@media screen and (min-width: 35em) {
  .grid-item {
    float: left;
    width: 50%;
  }
}

@media screen and (min-width: 60em) {
  .grid-item {
    width: 25%;
  }
}

As a basic grid system, it'll do the job. However, what if you wanted 2 columns on another section, 6 columns on the next and a 3 column grid on your about us page? Well then you're s**t out of luck.

Perhaps you'd go with a more robust grid system using a preprocessor like Susy where you call mixins on existing classes to extend their properties with grid based ones.

.about-us-main-content {
  @media screen and (min-width: 50em) {
    @include span(2 of 3); // 66% at 50em
  }
}

.about-us-sidebar {
  @media screen and (min-width: 50em) {
    @include span(1 of 3) // 33% at 50em
  }
}

.home-page-4-feature-panels {
  @include span(1 of 2) // 2 columns by default

  @media screen and (min-width: 50em) {
    @include span(1 of 4) // 4 columns at 50em
  }
}

Yep, that works. You'll have control of custom layouts depending on a section-by-section basis rather than having to conform to the same sizes each time. In addition, you're not limited by the breakpoints either as you could add these in with the use of media queries as shown above. So what's the downside? Well... bloat.

Every time you use the same grid output somewhere you're duplicating the compiled CSS code. Taking the Sass code below as an example

.feature-panels {
  @include span(1 of 4);
}

.footer-panels {
  @include span(1 of 4);
}

That would be compiled into something like...

.feature-panels {
  width: 25%;
}

.footer-panels {
  width: 25%;
}

or perhaps even this...

.footer-panels,
.feature-panels {
  width: 25%;
}

Whilst a simplified demo, it illustrates the problem of duplication. On smaller projects you can afford to get away with things like this, but when working on larger projects or projects with a larger performance budget then you're going to want to relook at the solution.

This in my eyes is where class-based grid systems come into play. Take a look at the HTML below.

<div class="grid home-panels">
  <div class="grid-item grid-item-1-4"></div>
  <div class="grid-item grid-item-1-4"></div>
  <div class="grid-item grid-item-1-4"></div>
  <div class="grid-item grid-item-1-4"></div>
</div>

<div class="grid footer-panels">
  <div class="grid-item grid-item-1-2"></div>
  <div class="grid-item grid-item-1-2"></div>
</div>

By consolidating all code into predefined classes we're cutting off any duplication we may have and by setting grid widths on the HTML rather than the CSS we've got complete control to the sizing of different sections or pages.

As an example, I actually created my own grid system last year called Groot which we've been using at Mixd since then and I'd definitely recommend it to those of you who would like to try out the concept. In addition, I know many larger companies are using these concepts, one of those being Sky thanks to a certain CSS Wizard so there's plenty of resources out there if you're looking to get started.

The future?

Anyhow, the future. Using Rory's concept we could utilise the style attribute to determine the size of a grid's item, rather than using a class.

Now I know what you're going to say, and generally speaking you're right. Normally the style attribute is frowned upon in modern CSS architecture due to it's lack of reusability and bloat from using the same code twice. However, in this instance with the use of variables, I think they're the perfect use-case.

<div class="grid footer-panels">
  <div class="grid-item" style="--grid-item-size: 50;"></div>
  <div class="grid-item" style="--grid-item-size: 50;"></div>
</div>

Mimicking the original class-based grid from before but with the use of variables for the sizing which is changing on a layout by layout basis.

In this example we've defined our style attribute as --grid-item-size: 50;. If we take a look at our imaginary grid system, we'd use that variable on the width of .grid-item.

.grid-item {
  width: var(--grid-item-size)%;
}

This would mean that you do not have to create separate classes for each variant, as well as being a little more semantic in my eyes, using the style attribute and variables for the layout states, rather than precompiled CSS. Ultimately, in a small system this will only shave off a few milliseconds in theory, if that, but I still think the workflow of using variables for conditional layouts is a good idea.

Thoughts? Hate mail? Questions? Leave a comment, I'd love to read them (not so much the hate mail).

Until next time 

Follow us on Twitter, Facebook or Github.
© Copyright 2021 Assortment.
Created and maintained by Luke Whitehouse.