Scalable, Modular CSS | BEM & ITCSS
James Basoo / January 15, 2015

Harry Roberts has done some amazing CSS architecture work of late. At GPMD we've found the scalable and modular principles he favours to be great for our Silverstripe and Magento projects. Here's how we like to do it.

Tools

grunt sass logo

We like using CSS preprocessors, usually Sass, though a task runner, usually GruntGrunt has some nice tasks for handling css that we use regularly:

We created grunt-frontend-boilerplate as a useful starting point for our Grunt workflow.

Architecture: ITCSS (Inverted triangle CSS)

ITCSS Boilerplate

The main aim of ITCSS architecture (slides) is to create a scalable, manageable, code base. This is done by writing modular, OOCSS and creating an upward trend of specificity within the stylesheet.

Take a look at our ITCSS boilerplate for an example structure.

Worth noting

  • We separate our css into 2 files, critical.css and main.css. You don't necessarily need to do this though, we've just been trying out deferring non-critical css for improved loading performance.
  • If you don't use a preprocessor, ignore the "Settings" and "Tools" layers below.

  1. Settings: Global variables config switches (colours, screen sizes)
  2. Tools: Functions and mixins
  3. Generic: Ground-zero styles (normalize/reset.css, box-sizing)
  4. Base: Unclassed HTML elements (type selectors)
  5. Objects: Unstyled design patterns (media object)
  6. Components: Styled objects, chunks of UI
  7. Theme (optional): Themed components, used for multiple sites with the same layout and components. Can be utilised for multi-site Magento setups.
  8. Trumps: Helpers and overrides, e.g. .float-left { float:left !important;}

Naming Methodology: BEM (Block, Element, Modifier)

When naming classes, we use a BEM style naming methodology. BEM effectively scopes your CSS so you only use the cascade then you actually want to.

.block {}
.block__element {}
.block--modifier {}

The point of BEM is to tell other developers more about what a piece of markup is doing from its name alone. By reading some HTML with some classes in, you can see how - if at all - the chunks are related; something might just be a component, a child, or an element of that component, and something might be a variation or modifier of that component. To use an analogy/model, think how the following things and elements are related:

.person {}
.person__hand {}
.person--female {}
.person--female__hand {}
.person__hand--left {}
<div class="person person--female">
    <div class="person__hand person__hand--left person--female__hand"></div>
</div>

If you don’t want to inherit the CSS of the person class, simply don’t add the class to the HTML. The same goes for if you want to style person__hand--left without the CSS from person__hand.

Conclusion

So, that's a broad overview of how we now like to structure our projects. It's proved itself to be very scalable, which makes working with platforms like Magento and Silverstripe that little bit easier.

In the future we'll take a closer look at how we integrate this into our Magento and Silverstripe projects so watch this space!