Silver, the simplest CSS grid ever

Most CSS grid systems are bloated, outdated, or complete overkill – hundreds or thousands of lines of properties you’ll never use – and popular only because of their popularity. So I made a smaller one:

.grid {
  display: flex;
  flex-wrap: wrap;
}

.column {
  box-sizing: border-box;
  flex: 1;
}

.bigger {
  flex: 2.5;
}

.halves .column  { flex: 0 0 50%; }
.thirds .column  { flex: 0 0 33.3333%; }
.fourths .column { flex: 0 0 25%; }

@media (max-width: 900px) {
  .grid { display: block; }
}

It’s super easy to use, with plain English class names and simple documentation. Yet it can handle quite a few layouts:


Flexible Columns

Space is automatically divided between the number of columns in the grid. In the following examples, the only difference is the number of children:

Col 1
Col 2
Col 3
<div class="grid">
  <div class="column">Col 1</div>
  <div class="column">Col 2</div>
  <div class="column">Col 3</div>
</div>
Col 1
Col 2
Col 3
Col 4
Col 5
Col 6
<div class="grid">
  <div class="column">Col 1</div>
  <div class="column">Col 2</div>
  <div class="column">Col 3</div>
  <div class="column">Col 4</div>
  <div class="column">Col 5</div>
  <div class="column">Col 6</div>
</div>
Col 1
Col 2
<div class="grid">
  <div class="column">Col 1</div>
  <div class="column">Col 2</div>
</div>

Contrast this with something like Bootstrap.


Wide Columns

Applying the bigger class to a column will give it more width than its siblings. A use case for this would be to denote the main content from sidebars:

Col 1
Col 2
<div class="grid">
  <div class="bigger column">Col 1</div>
  <div class="column">Col 2</div>
</div>
Col 1
Col 2
Col 3
<div class="grid">
  <div class="column">Col 1</div>
  <div class="bigger column">Col 2</div>
  <div class="column">Col 3</div>
</div>

Increase or decrease this width by changing the value of .bigger.


Fixed Grids (“only x per row”)

Display a fixed number of columns per row by adding an additional class to the container div. This comes in handy when populating UI with data from a list (think of the grid on an Instagram profile).

Even though there are four children, the grid now displays two per row:

Col 1
Col 2
Col 3
Col 4
<div class="grid halves"> <!-- "halves" -->
  <div class="column">Col 1</div>
  <div class="column">Col 2</div>
  <div class="column">Col 3</div>
  <div class="column">Col 4</div>
</div>
Col 1
Col 2
Col 3
Col 4
Col 5
Col 6
<div class="grid thirds"> <!-- "thirds" -->
  <div class="column">Col 1</div>
  <div class="column">Col 2</div>
  <div class="column">Col 3</div>
  <div class="column">Col 4</div>
  <div class="column">Col 5</div>
  <div class="column">Col 6</div>
</div>
Col 1
Col 2
Col 3
Col 4
Col 5
Col 6
Col 7
Col 8
<div class="grid fourths"> <!-- "fourths" -->
  <div class="column">Col 1</div>
  <div class="column">Col 2</div>
  <div class="column">Col 3</div>
  <div class="column">Col 4</div>
  <div class="column">Col 5</div>
  <div class="column">Col 6</div>
  <div class="column">Col 7</div>
  <div class="column">Col 8</div>
</div>

Read details on extending the grid to support more columns below.


Columns Nested In Other Columns

And if you need to go deeper (cue Inception noise), just make another grid inside a column.

A
B
C
Col 2
<div class="grid">
  <div class="column">
    <div class="grid">
      <div class="column">A</div>
      <div class="column">B</div>
      <div class="column">C</div>
    </div>
  </div>
  <div class="column">Col 2</div>
</div>

I’ve added padding around A, B, and C so you could get the gist of what’s happening here. By default, this padding would not exist.

You can also fix the grids to a certain number of columns. For instance, four-wide on the left and one column on the right.

A
B
C
D
E
F
G
H
Col 2
<div class="grid">
  <div class="column">
    <div class="grid fourths"> <!-- "Fourths" -->
      <div class="column">A</div>
      <div class="column">B</div>
      <div class="column">C</div>
      <div class="column">D</div>
      <div class="column">E</div>
      <div class="column">F</div>
      <div class="column">G</div>
      <div class="column">H</div>
    </div>
  </div>
  <div class="column">Col 2</div>
</div>

Example Blog Post Layout

This simple markup creates a blog post layout with wide content and a sidebar with grids:

Content
happy little sidebar

G
R
I
D
<div class="grid">
  <div class="bigger column">Content</div>
  <div class="column">
    happy little sidebar
    <br />
    <br />
    <div class="grid halves">
      <div class="column">G</div>
      <div class="column">R</div>
      <div class="column">I</div>
      <div class="column">D</div>
    </div>
  </div>
</div>

Details

Spacing

By default, there is no space between columns. If you’d like to add simple spacing, I recommend adding padding to the .column class1:

.column {
  padding: 1rem;
}

If your project requires a lot of custom spacing, add the spacing to your child elements instead.

Mobile

I rigged this post so none of its examples break on smaller screens (for all of you mobile readers out there). However, the grid’s default behavior is to expand each column to fullwidth at 900px. This behavior is changable via the media query. Add multiple media queries if you’d like more customization over the layout.

Extending Fixed Grids

The grid supports two, three, and four fixed columns out of the box. To add support for another one, just create another class and divide 100 by the number of columns you’d like to use:

.fifths .column  { flex: 0 0 20%; }   /* 100 divided by 5 */
.eighths .column { flex: 0 0 12.5%; } /* 100 divded by 8 */
.tenths .column  { flex: 0 0 10%; }   /* 100 divided by 10 */

Changing Width of “Bigger” Columns

As noted in the examples above, giving a column the class bigger will increase its size relative to its siblings. To change the width of bigger columns, change the value of flex:

.bigger {
  flex: 2.5; /* Increase = Bigger Width */
}

How “flex” shorthand works

The grid’s small footprint is possible because of flexbox. I take advantage of the shorthand for flex to make it work:

.flexy {
  flex: flex-grow flex-shrink flex-basis;
}

.bigger uses flex-grow and fixed grids use flex-basis.

Browser Support

This grid uses basic flexbox properties which are supported by modern browsers.

Naming Conventions

I like to use simple class names (“bigger column”) because I do a lot of React development with CSS Modules (which locally scopes your CSS so you don’t encounter cross-application style conflicts). This code is short enough that you can change the class names to fit your preferences in a few seconds.

  1. In this case, padding is better than margin because margin isn’t factored into the element’s width when using fixed-column layouts. If you want to use margin instead of padding, add it to a child element of a column instead. ↩︎