home file-empty pencil screen user heart reply share social loading

Keith J. Grant

Photo of Keith

Atlanta, GA
United States

Twitter
@keithjgrant
Github
keithjgrant
Author
CSS in Depth

JavaScript, CSS, UX, & the open web

OOCSS and Grid

OOCSS was the first of the many CSS methodologies. Since it arrived on the scene, the industry has moved on to newer, more strongly prescriptive methodologies like SMACSS, BEM, and ITCSS. These newer approaches dominate the conventional wisdom today. But CSS grid is here now, and I find it presents some challenges to this wisdom. I think it’s time we give OOCSS a little attention again, because it has an important idea to offer in the world of CSS grid.

A major theme recently is an emphasis on modular design: a user interface broken up into small modules whose styles are encapsulated. Modules are nested one within another to construct the entire interface. This leads to markup that looks something like this:

<div class="row">
  <div class="col-4">
    <div class="card">
      <h3 class="card__title">Wash</h3>
      <p class="card__body">The whacky pilot.</p>
    </div>
  </div>
  <div class="col-4">
    <div class="card">
      <h3 class="card__title">River</h3>
      <p class="card__body">The mysterious prodigy. She kicks serious ass.</p>
    </div>
  </div>
  <div class="col-4">
    <div class="card">
      <h3 class="card__title">Jayne</h3>
      <p class="card__body">The strongman.</p>
    </div>
  </div>
</div>

You have one module responsible for layout (row and col-4 classes) and another responsible for the look of the of the items within the layout (card and card__* classes). I used the classes from the Bootstrap grid system here, but this pattern isn’t limited to bootstrap: it’s common to use one module for layout and another for visual appearance like colors, fonts, and borders.

A Limitation of CSS Grid

As I work with the new CSS Grid layout, I’m finding that the conventional approach isn’t always feasible. The big restriction with grid is this: to align an element in a grid, it must be a direct child of the grid container. (This may not be a limitation forever, but for now, we need to live with it.)

Take the example above, for instance. If you were to replace the row and col-4 classes with a proper grid, you could not align the card elements directly to the grid:

<div class="grid">
  <div class="grid__item">
    <div class="card">
      <h3 class="card__title">Wash</h3>
      <p class="card__body">The whacky pilot.</p>
    </div>
  </div>
  <div class="grid__item">
    <div class="card">
      <h3 class="card__title">River</h3>
      <p class="card__body">The mysterious prodigy. She kicks serious ass.</p>
    </div>
  </div>
  <div class="grid__item">
    <div class="card">
      <h3 class="card__title">Jayne</h3>
      <p class="card__body">The strongman.</p>
    </div>
  </div>
</div>

When you do this, the grid items align to the grid, each filling their respective grid cells, but the cards do not. This is the result:

Three white cards of different heights

Instead of three neatly-aligned cards, the heights are all different. The grid items each have an equal height, but this is invisible to the user. The cards—and their white backgrounds—within don’t fill the entire height of those grid items. (This example is available on Codepen.)

OOCSS to the Rescue

OOCSS offers a solution to this problem. Let’s blow the dust off this old book and take a fresh look at what it offers. OOCSS is much simpler than the newer CSS methodologies. It has just two rules:

First, Separate Container and Content. This means styles should not be location-dependent. A module should work no matter where you place it in the DOM. If you follow SMACSS and/or BEM, this is exactly what you’re doing with your modules.

The second rule, however, isn’t followed as often in our newer methodologies: Separate Structure and Skin. This means one class should be used to apply the structure to an element—its position and shape—while another should be used to apply its “skin”—its colors and stylistic appearance. Ideally, the same skin could be applied to a number of different “structures.”

After years of working with BEM, this second rule feels foreign. We’re used to each module (or “block,” if you prefer) doing its thing. Any given DOM element belongs only to one module. It feels dirty to apply two different modules to the same element: one for skin and another for structure. But I think this skinning approach going to be useful in the world of CSS grid.

Watch what happens in our example, when we combine the grid item “structure” with the card “skin”, thereby removing one layer of depth from the DOM:

<div class="grid">
  <div class="grid__item card">
    <h3 class="card__title">Wash</h3>
    <p class="card__body">The whacky pilot.</p>
  </div>
  <div class="grid__item card">
    <h3 class="card__title">River</h3>
    <p class="card__body">The mysterious prodigy. She kicks serious ass.</p>
  </div>
  <div class="grid__item card">
    <h3 class="card__title">Jayne</h3>
    <p class="card__body">The strongman.</p>
  </div>
</div>

Now, the card styles are applied directly to the grid items (See this example on Codepen):

Three white cards of equal heights, aligned correctly to the grid

It’s important with this approach to maintain a distinction between “structure” modules and “skin” modules, so you don’t accidentally mix two skins together for conflicting results. On the whole, that’s not too hard to do. It just takes some good old fashioned OOCSS.

Loading interactions...

Recent posts