Silver, the smallest CSS grid ever

December 17, 2017

Most CSS grid systems are complete overkill. So I wrote 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; }
}

That tiny snippet can make all of these layouts (and more):


Flexible Columns

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

Col 1
Col 2
<div class="grid">
  <div class="column">Col 1</div>
  <div class="column">Col 2</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>

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>

If you need to support more than four columns, read the details at the bottom of this page.


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

If you want to add spacing between columns, either 1 add it to your child elements, or 2 adding padding (not margin) to the .column class:

.column {
	padding: 1rem;
}

Extending Fixed Grids

To add support for more than a four-column fixed grid, 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 divided 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 to make the column bigger */
}

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;
}

Browser Support

flexbox is supported by all modern browsers and has partial support in IE 11.

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.