Atomic CSS as a tool set

The growing complexity of websites and web applications has yielded several new approaches to structuring and maintaining style sheets. You may have heard of BEM, OOCSS, SMACSS, OrganicCSS, or Atomic CSS. We used the latter, Atomic CSS, to design our new golucid.co website. We’d like to share with you where it helped, where it hurt, and how we found a balance.


What is Atomic CSS?

Let’s start with a simple definition. As the name suggests, the core principle of Atomic CSS involves breaking down styles into atomic, or indivisible, pieces. This is fundamentally contrary to the traditional approach of writing semantic selectors. Contrast the two CSS snippets below:

Semantic CSS Atomic CSS
.nav-link {
    float: left;
    margin-right: 16px;
    color: white;
}

.nav-link-selected {
    color: teal;
}
.fl-st { float: left; }

.mr-1 { margin-right: 16px; }

.c-w { color: white; }

.c-pr { color: teal; }

As you can see, the atomic styles are pretty agnostic of the markup. In comparison, the semantic styles allow an experienced CSS author to view the stylesheet and get a good idea of what an element will look like.


How it works

The paradigm shift with atomic CSS is that most of the styling decisions reside in the markup rather than explicitly in the stylesheet. (Try to ignore that voice in your head screaming about separation of concerns—we’ll get to the good part in a moment!) For example, consider the styles and markup for the very common media component, as seen on the Executive Team section of golucid.co:

LESS HTML
@std-margin: 16px;

.mt-1 { margin-top: @std-margin; }
.mr-1 { margin-right: @std-margin; }
.mt-2 { margin-top: 2*@std-margin; }

.ov-h { overflow: hidden; }

.d-b {  display: block; }

.va-m {  vertical-align: middle; }

.fl-st { float: @float-start; }
.fl-nd { float: @float-end; }

.fw-b {  font-weight: bold; }

.fs-i {  font-style: italic; }

.headshot {
    width: @headshot-dimension;
}
<ol class="mt-1">
    <li class="mt-2 ov-h">
        <img ... class="headshot d-b va-m fl-st mr-1">
        <div class="executive-bio ov-h">
            <a ... class="fl-nd">
            	<img ... />
            </a>
            <h3 class="fw-b">Karl Sun</h3>
            <h4 class="fs-i">CEO and Co-founder</h4>
            <p>Prior to Lucid Software...</p>
        </div>
    </li>
    ...
</ol>

Note that there are very few semantic classes, which are only used for specific needs. The rest of the styling information comes from the groups of highly-abbreviated atomic classes; those familiar with Emmet will recognize the abbreviations. And really, there aren’t that many classes on the various elements. The power of this approach is that we didn’t have to write a new selector with redundant styles for every possible combination of atoms. Let’s delve a little deeper into that idea.


Reducing code redundancy and size

Atomic CSS is all about fighting the bloat that our stylesheets tend to acquire. Consider the following snippet of semantic CSS:

CSS HTML
.nav-link {
    float: left;
    margin-right: 16px;
    color: white;
}

.footer-link {
    float: left;
    margin-right: 16px;
    color: teal;
    font-size: 85%;
}

.body-img {
    float: left;
    margin-right: 16px;
    margin-bottom: 16px;
}
<a class="nav-link" ... >
foo</a>

<a class="footer-link" ... >
bar</a>

<img class="body-img" ... />

You’ll note that there are several instances of the margin property with the same value. Smelling the duplicate code, a preprocessor-savvy author may substitute the value for a variable, like so:

LESS HTML
@std-margin: 16px;

.nav-link {
    float: left;
    margin-right: @std-margin;
    color: white;
}

.footer-link {
    float: left;
    margin-right: @std-margin;
    color: teal;
    font-size: 85%;
}

.body-img {
    float: left;
    margin-right: @std-margin;
    margin-bottom: @std-margin;
}
<a class="nav-link" ... >
foo</a>

<a class="footer-link" ... >
bar</a>

<img class="body-img" ... />

It’s nice that there are no hard-coded duplicates and that any changes to the margin size can be done in one place. Plus, the actual CSS output is unchanged. In fact, preprocessor variables and mixins used in this way really only make the source stylesheets more manageable, while leaving the CSS output essentially unchanged (at best) or even more bloated (at worst).

Let’s reproduce our styling using the atomic approach:

LESS HTML
@std-margin: 16px;

.fl-st { float: left; }

.mr-1 { margin-right: @std-margin; }
.mb-1 { margin-bottom: @std-margin; }

.c-w { color: white; }
.c-pr { color: teal; }

.fz-sm { font-size: 85%; }
<a class="fl-st mr-1 c-w" ... >foo</a>

<a class="fl-st mr-1 c-pr fz-sm" ... >bar</a>

<img class="fl-st mr-1 mb-1" ... />

The atomicity of the pieces is conducive to minimal CSS bloat and optimal code reuse. Indeed, the HTML is more bloated because of the increased number of class names in use, but the designers at Yahoo have reported a net savings in total size between the CSS and the HTML.


Why not just use inline styles?

At this point you may be asking yourself, How this is any different/better/worse than just using inline styles in my HTML?

First, inline styles are king in the realm of specificity. Atomic CSS classes are just simple classes with low specificity, meaning that you can override atomic css styles easily and comfortably without nasty specificity chaining.

Second, inline styles are unsightly, bloat your HTML like crazy, and are hard to maintain. Atomic stylesheets are clean, concise, and highly maintainable.


Why you should try it

Now for the hard sell—you should really try it. We’re not saying it’s the perfect solution to all your CSS challenges, but it’s certainly a tool worth exploring. Here’s why we like it so far:

Style consistency

Having a tight core of standard styles keeps your visual design consistent. Having standard margin or padding values, for instance, will ensure that elements are spaced evenly and consistently throughout your site or application.

Atomic styles make change easy

Say you want to change your standard margin from 16px to 20px, or switch your primary color from blue to purple. With inline styles, you’d have to go through the entire project to find and replace them all. With an atomic stylesheet, you just make the changes in a few places. You’ll probably only need to change it in one place if you’re using a CSS preprocessor and variables.

Improved Workflow

Atomic CSS lets you build the basic stuff quickly. That way, you can spend your time writing custom styles for the more interesting elements of your design. The best part about using atomic styles to build golucid.co was that we didn’t need to write new styles for each new HTML element. On several occasions, we started writing new semantic classes only to realize that the same styling could be applied with just our atomic classes. The stylesheet started small and stayed that way.


Caveats

Though we found advantages with the atomic approach, we also came across some shortcomings, the most prominent of which was dealing with responsive designs. For example, if your main section has the class m-3 for a 30px margin, but you’d like to reduce that to 15px at a small device width, you would need to use another class like m-3-sm in addition to your m-3 class. At this point, the 3 in m-3-sm loses some of its meaning. It’s easy to see that adding a lot of responsive-specific classes could make the markup unwieldy and the stylesheet larger.


Conclusion

Atomic CSS is a great tool when adjusted to meet your needs. For example, you could use semantic classes for visual styling (colors, borders, backgrounds, etc.) and use atomic classes for spacing and layout. You can also create slightly more complex classes for your atomic style sheet that replace a commonly occurring set of styles (some call these classes “molecules”). What’s important is that Atomic CSS meets your needs instead of the other way around.

Remember: tools, not rules.


If you want a place to get started with atomic styles, you can check out Alma’s atomic-css GitHub project.


Update 3/20/14:
Many thanks to Thierry Koblentz for his excellent article, Challenging CSS Best Practices, that introduced us to the ideas of atomic css.


6 Comments

  1. Thanks for the notice Thierry. Our apologies for not citing your article in the first place.

  2. If you’re going to go with Atomic rather than Semantic css technique, you need to make sure your mockups allow for that. Meaning your mockups need to be designed with reusable elements in mind, and secondly, your mockups need to get approved and signed off by the client. Once you do that, then there is no need to change the m-3 class to m-3-small in the markup, and no need to change global color from blue to red. If you are changing margins and color too frequently in your development process, then either you’re having communication problems with your client, or your mockups are poorly made.

    The way I understand it is good css coding techniques began with good mockups that allow for that.

  3. Hello, i like Atomic CSS architecture and popularize it among people.
    I want to introduce you cool toolset for Atomic CSS developers.
    Orna, Atomic CSS industry
    https://github.com/OrnaOrg

  4. […] DesignAtomic CSS as a tool setChallenging CSS Best PracticesThe “Other” Interface: Atomic Design With SassYour Frontend […]

Your email address will not be published.