CSS Structural Concepts
I recently attended “An Event Apart” a conference about the latest in design, UX, and development, and a talk by Nicole Sullivan inspired me to look deeper into CSS structure and some of the prevailing paradigms. The goal of this blog post is to share the latest in CSS structure and organization paradigms with you, and hopefully give you a high-level explanation of how they can work together or independently to help you level-up your CSS.
The paradigms that I want to unravel in this post are the following:
Throughout the article I will reference a Github repo called Holy Grail, which is a living example of these concepts. I highly recommend opening that repo as well as the live site and following along as you read this post. It will make many of the concepts clearer, if only through repetition.
Below you can see the live site that those folks built on the left, accompanied on the right hand by my developer tools, open to the ‘sources’ tab which allows me to view the CSS loaded on each page. The site has a separate page demonstrating each of the concepts that I am going to explain.
SMACSS stands for “Scalable and Modular Architecture for CSS”. It’s a (free) book and a methodology for writing CSS, created by Jonathan Snook. Its most significant and influential aspect is its organizational system, which is designed to provide a set of buckets into which CSS should be organized. To learn more, check out the SMACSS web site and read or order the book there.
The primary organizational buckets defined in SMACSS are Layouts and Modules. The parent folder for ‘Layout’ defines grids, responsive frameworks, wrappers and gutters. The parent folder for ‘Modules’ contains the majority of the site CSS, broken up into logical units, generally these are the same units that are called ‘objects’ in OOCSS and ‘Blocks’ in BEM (we will get into this later).
An example project following SMACSS might look like this:
│ └── grid.css
│ ├── header.css
│ ├── footer.css
│ └── card.css
│ ├── dark.css
│ └── light.css
OOCSS focuses on flexible, modular, swappable components that do ‘One Thing Well’. OOCSS focuses on the single responsibility principle, separation of concerns, and many more foundational concepts of Object Oriented Programming.
Fundamentally, it’s about creating a parent class that defines a CSS module, and then using the right level of specificity to define the styles within that component. Let’s take an example:
In the above example, the footer is a module: it defines a specific (reusable) chunk of styles attached to markup. The elements that can be created within the footer are also defined with classes, which creates the right level of specificity to use the footer styles on other markup.
Subconcepts of OOCSS are as follows:
Structure vs. Skin
This principle of object oriented CSS says “separate the core presentation styles from instance-specific styles”. In the example below you can see that I’ve got two buttons that need to both behave like buttons (the text alignment must be centered, it should have a border-radius)
Container vs. Content
This OOCSS concept says “Don’t use location-dependent styles”. Make your styles applicable anywhere, as opposed to being tied to a specific use-case or piece of HTML. let’s look at an example:
In the above example, we allow re-use of the nav-header style regardless of the HTML present (it could be an h2, h3, h6 and we could still re-use our styles).
Presentational vs. Semantic Class Names
OOCSS does not take a stand on presentational vs. semantic class names, but instead leaves that up to you as a developer to decide when to use one or the other.
BEM is a specific concrete application of OOCSS. BEM stands for “Block Element Modifier”, and it describes a pattern for naming CSS object class names. In the description below I will use a traditional form of BEM, described best by CSS Wizardry’s post titled MindBEMding. There are many flavors of BEM, that you can investigate here if you are interested.
Essentially, each BEM class starts with a block, which is an object name. Let’s start with
.byline. Then, for children of that block, you add an element, separating it with two underscores:
.byline__name. Finally, you can modify any class (block or element) by adding a modifier, separated with two hyphens:
Here’s the previous Footer example rewritten in BEM syntax:
Using these concepts in tandem
As you may have guessed by now, these concepts are not at all mutually exclusive. SMACSS actually builds some of the concepts of BEM and OOCSS into the file structure, and BEM is really a subset or expansion of OOCSS in itself. Therefore it’s very natural and symbiotic to combine these concepts. Here is an example file structure incorporating SMACSS and BEM/OOCSS all in one.
Depending on the complexity of the site, we will likely have a folder dedicated to layout. Grids, responsive frameworks, wrappers, etc. would all live here.
Includes definitions for our modules, blocks or objects. The goal is for as much code to exist in here as possible, making it flexible and reusable. This file will just be a list of modules defined (and documented) one after another. An example CSS file in this folder would be
footer.css containing the block level styles for the footer module that we’ve been following in this article.
The name for this partial varies, but essentially this is all the code that doesn’t fit in
_modules. Code we just couldn't make modular; glue between modules; top level layouts; etc.
normalize.css, and also sets styles on base elements:
Thanks for reading, I hope that you found some of the information in this article useful, see you next time!