Developer Ben Frain once remarked that it’s easy to write CSS code, but it is hard to scale and support it. This article describes the set of solutions out there to deal with this problem.
OOCSS

OOCSS stands for object-oriented CSS. This approach has two main ideas:
- Separation of structure and design
- Separation of container and content
Using this structure, the developer obtains general classes that can be used in different places.
At this step, there are two pieces of news (as usual, good and bad):
- Good: reducing the amount of code by reusing it (DRY principle).
- Bad: complex support. When you change the style of a particular element, you will most likely have to change not only CSS (because most classes are common), but also add classes to the markup.
Also, the OOCSS approach itself does not offer specific rules, but abstract recommendations, so how this method ends up in production varies.
As it happens, the ideas in OOCSS inspired others to create their own, more concrete, ways of code structuring.
SMACSS

SMACSS stands for Scalable and Modular Architecture for CSS. The main goal of the approach is to reduce the amount of code and simplify code support.
Jonathan Snook divides styles into 5 parts:
- Base rules. These are styles of the main website elements – body, input, button, ul, ol, etc. In this section, we use mainly HTML tags and attribute selectors, in exceptional cases – classes (for example, if you have JavaScript-style selections);
- Layout rules. Here are the styles of global elements, the size of the cap, footer, sidebar, etc. Jonathan suggests using id here in selectors since these elements will not occur more than 1 time on the page. However, the author of the article considers this a bad practice (whenever an id appears in the styles, somewhere in the world the kitten is sad).
- Modules rules. Blocks that can be used multiple times on a single page. For module classes, it is not recommended to use id and tag selectors (for reuse and context independence, respectively).
- State rules. In this section, the various statuses of the modules and the basis of the site are prescribed. This is the only section in which the use of the keyword “! Important” is acceptable.
- Theme rules. Design styles that you might need to replace.
It is also recommended to enter the namespace for classes belonging to a certain group, and also to use a separate namespace for the classes used in JavaScript.
This approach makes it easier to write and maintain code, and has attracted a large number of developers.
Atomic CSS

With Atomic CSS, a separate class is created for each reusable property. For example, margin-top: 1px;
assumes creation of a class mt-1
or width: 200px;
the class w-200
.
This style allows you to minimize the amount of CSS-code by reusing declarations, and it’s also relatively easy to enter changes into modules, for example, when changing a technical task.
However, this approach has significant drawbacks:
- Class names are descriptive property names, not describing the semantic nature of the element, which can sometimes complicate development.
- Display settings are directly in the HTML.
Because of these shortcomings, the approach has been met with a significant amount of criticism. Nevertheless, the approach can be effective for large projects.
Also, Atomic CSS is used in various frameworks to specify corrective element styles and in some layers of other methodologies.
MCSS

MCSS is Multilayer CSS. This style of code writing suggests splitting styles into several parts, called layers.
- Zero layer or foundation. The code responsible for resetting browser styles (e.g. reset.css or normalize.css);
- Base layer includes styles of reusable elements on the site: buttons, input fields for text, hints, etc.
- Project layer includes separate modules and a “context” – modifications of the elements depending on the client browser, the device on which the site/application is viewed, user roles, and so on.
- Cosmetic layer is written the OOCSS style, making minor changes in the appearance of elements. It is recommended to leave only styles that affect the appearance and are not capable of breaking the layout of the site (e.g colors and non-critical indents).
The hierarchy of interaction between layers is very important:
- The base layer defines neutral styles and does not affect other layers.
- Elements of the base layer can only affect the classes of its layer.
- Elements of the project layer can affect the base and project layers.
- The cosmetic layer is designed in the form of descriptive OOCSS-classes (“atomic” classes) and does not affect other CSS-code, being selectively applied in the markup.
AMCSS

AMCSS is “Attribute Modules for CSS”.
Let’s look at an example:
<div class="button button--large button--blue">Button</div>
Such a chain of classes is not simple, so let’s group these values by attributes.
Here’s what happens:
<div button="large blue">Button</div>
To avoid names collisions, it’s a good idea to add namespaces to the attributes. Then our button code takes the following form:
<div am-button="large blue">Button</div>
If you use the validator to check the code and it doesn’t like the am-button
attribute, you can prefix data-
before the attribute name.
A little-known selector “~=” (IE7+) is used, which works as a class attribute: it selects elements whose attribute values contain the specified words, separated by spaces. So, the selector of the form [class~="link"][class~="button"]
is similar to the selector a.link.button
. Even by specificity, since the selector specificities for the class and the attribute are equal to each other!
Accordingly, the CSS code
.button {...}
.button--large {...}
.button--blue {...}
Converts to
[am-button] {...}
[am-button~="large"] {...}
[am-button~="blue"] {...}
If you think this code is too unusual, you can use a less radical AMCSS form:
<div am-button am-button-large am-button-blue></div>
FUN

FUN stands for Flat hierarchy of selectors, Utility styles, Name-spaced components.
There is a certain principle behind each letter of the name:
- F, flat hierarchy of selectors: it is recommended to use the classes to select items, avoid a cascade without the need, and do not use ids.
- U, utility styles: it is encouraged to create the service atomic styles for solving typical makeup tasks, for example,
w100
forwidth: 100%;
orfr
forfloat: right;
- N, name-spaced components: Ben recommends to add namespaces for specifying the styles of specific modules elements. This approach will avoid overlapping in class names.
Some developers note that the code written using these principles is quite convenient to write and maintain; in some way, the author took the best from SMACSS and laid out this technique in a simple and concise manner.
This approach imposes quite a few requirements on the project and the code structure, it only establishes the preferred form of recording selectors and the way they are used in the markup. But in small projects, these rules can be quite enough to create high-quality code.
Conclusion
As you can see, there is no ideal one among these approaches. Therefore none of these methods is an absolute rule – you can take an approach from begin to create something of your own, or create a new approach from scratch.
Good recap, thanks.
What did you use for your diagrams?
Thanks for the article! It would be nice to create a survey to find out what are the most used among the developers.
Thank you so much for this post.
I already know OOCSS, SMACSS but not the others.
And what about BEM (bloc, element, modifier) ?
I would think that BEM would be a contender for one of the most popular ways to organize CSS.
I’m surprised not to see what I believe to be one of the most popular methodology : BEM (Block-Element-Modifier) and its derivative.
http://getbem.com/
Great article anyway, thank you :)
The “significant drawbacks” sited for Atomic CSS are actually benefits in my opinion:
The “semantic nature” of the element is sufficiently defined by element tags (a, p, header, nav, etc) and the names of components in your template structure (card.tag, etc).
Some people find it easier to reason about display settings when they see them in the markup without having to drill into CSS to see what was defined where.
I thought there was going to be something here about ITCSS. I like it very much so far!
You can see ITCSS here http://www.creativebloq.com/web-design/manage-large-css-projects-itcss-101517528
Hi Inessa,
I think it is worth saying that the drawbacks you mention regarding Atomic CSS only exist for people who buy into the “Separation of Concerns” (semantic class names”)*. See “Opinions of leaders considered harmful“.
Was going to say the same thing. Exactly how do semantic class names benefit a project? They don’t benefit search engines, end users or accessibility tools. So why is this considered a drawback… no less a “considerable” one?
I’m so sorry Thierry. ACSS really is cool…
@Ben Of course there’s no advantage for the user when using semantically meaningful CSS classes. The advantage here is for the developers: you get a much clearer idea of what something is for with classes like
submit-button
rather thanc-green ph-10 pv-5 m-5
.If you componentize your templates into separate files for a template engine, then I’d say atomic design makes a lot of sense. You know the context by the component’s name and you get to understand exactly what it is doing with atomic classes.
You mentioned a comment from Ben Frain at the beginning of the article. He might appreciate you mentioning ECSS. He wrote the book.
I would also suggest investigating BEM and ITCSS.
CSS Modules is missing as well. I belive it’s the holy grail in the current “component meta”.
I’ve never used atomic CSS for a personal project but I have had to customise the appearance of an existing atomic CSS project. It’s AWFUL!!
Due to the developer not declaring semantic classes, there is nothing to attach style rules to. Want to change a colour for one element? Too bad. It’s defined as orange, it’ll stay as orange.
The only way to override the CSS is to either use sibling class selectors (if no other orange element has the same sibling classes) or hierarchical selectors. Both are awful and a hack. shudders
We’ve been using a form of FUN for some time on our projects. And have found a universal set of styles for structure that we can use on every single site, form, design, you name it. This became our foundation. This foundation gets iterated and improved over time.
Then we found that it was good to have a default site set of styles for a site over top of this. Standard coloring, font formatting etc, with media queries specific to a site.
Next, a simple extra css file that was purposed from line one to never require any order or cascading. This meant that we could add any customizations to this document without any future maintenance concerns, because we all know the styles here don’t rely on any cascading effects in itself. So everything can be easily added to the top of the document without worry. (fewer worries make work faster)
Last, page specific styles. For example, the home page has a funky element not used anywhere else, stick it in the home.css file, done. This avoids any needs for inline styles, or messy inserts into any other longer or generalized css files. And any funky style needs for a single page are easily managed well into the future.
Foundation > Site > Extra > Page
It doesn’t make a cute acronym though. (FoSEP? :P ) At the worst, it is 4 http requests, optimized it’s 2 (FSE, and then page separate), or HTTP2 for the rescue down the road.
What are your thoughts on the React trends of keeping the CSS alongside the component?
The first attempt was done with inline styles, but that’s been replaced with more sophisticated tools like Aphrodite, which generates tags and places the CSS in them as components load
Nice article. Amazing CSS information at one place.
The following is all implicitely IMO.
This is a good recap but I think from the point of view of the modern, “componentized” and locally scoped CSS development these approaches are all kind of moot. It’s actually quite notable that BEM isn’t mentioned here, although it’s the best of the bunch when it comes to components.
If there’s one methodology that has to die is Atomic CSS. The minor advantages (smaller style sheets, for examples) are greatly overwhelmed big huge flaws, namely:
it tightly couples the style code with the Atomic CSS framework used to generate the classes (no, there’s not just Tachyons);
the conventions used to name the classes, in search for brevity, imply a learning curve and are often unclear (does
b-10
refer to the border, or to thebottom
property? Is aw-20
box 20 pixels large, orem
s, or points, or %?);Atomizer solves the above, but the result is of course longer class names, and it leads to the next problem: for each element you may end up with a dozen of class names, possibly all crammed in a single line (i.e., a pain to read);
of course you can split HTML attributes into several lines, but that OTOH compromises the readability of the HTML as a whole;
it won’t age well as new CSS modules are added to the specifications;
media queries complicate everything;
it’s misleading, as it leads to a representation of what the developers/designers see the result, but it’s not always how it’s presented to the user: something lime
bg-blue
lose all its meaning on an e-ink display or a screen reader.it pushes developers to just use atomic classes and forget about semantic ones that can be used for references and namespaces for surrounding and descending elements (e.g. the first paragraph after a heading, or alternating rows in a table);
as a consequence, it moves the presentational logic from CSS to HTML and even JavaScript, where you need to generate dynamic content;
it doesn’t offer a clear solution for more complex element states (i.e. not just
:focus
or:hover
, but something like “selected” or “mail-sent”).That’s just a bunch of problems that comes to my mind and maybe I’m forgetting some. But the conclusion is: Atomic CSS is a pain to learn, to use and to maintain.
If you like it, I’m not saying you can’t be my friend, but… don’t ask me to develop something together. :)
It may not be a silver bullet, but I think it depends on your needs and the context of your situation. As both a designer and developer I find it very appealing as an easily portable starting point for new projects and rapid prototyping during the iterative stages of development. I forget what photoshop even is these days. Especially in a component based single-page app I’ve found it makes building components a fast process. Those components themselves act as semantic references and, as mentioned above, sometimes the element itself can provide plenty semantic information.
I would invite you to read this article:
You will see that abbreviation isn’t always used. And the problem you see with the learning curve needed for abbreviation is a bit silly. All you need is a documented reference for each abbreviation, and once you’ve been working with it for a while the reference becomes unnecesssary. The learning curve is not steep at all in fact it’s quite elementary.
I personally don’t use abbreviation and I like using BEM to communicate how a block is nested when it comes to building monolithic components. I follow a similar style to this:
http://solid.buzzfeed.com/
I’ve read that article when it came out.
The problem about learning a new syntax is real and well present. It needs commitment from all the developers. I.e., you just cannot use Atomic CSS once in a while, or you will forget about the conventions you used and be forced to study them all over again.
And that’s what would happen in a company, like the one where I work at, which mainly provides external consultancy and often has to deal with code bases that are conceived elsewhere.
And fortunately we’ve never met a project developed using Atomic CSS, because we’d have to learn another tool and (probably poorly documented) setup prior to do any work. And even if we used Atomic CSS chances are that they could have used different conventions for their classes.
In fact the culprit here is that Atomic CSS implies another arbitrary layer of abstraction on top of CSS. A layer that has to be learnt and used consistently, while we could use those resources to be immediately productive.
Of corse, we’ve met far worse stuff like 8000-lines long CSS files with spaghetti-like classes and declarations, with lots of id’s and !important stuff. Things that makes you curl in a corner and cry. Atomic CSS would have meant at least an effort to organize the code.
But when it comes to projects that begins from us, a classic, component-driven SCSS code base still feels more natural for us.
Atomic CSS is what I use AT WORK now. I create and support an ASP.NET web application. It seems to work best for me NOW because we have many programmers that don’t know a lot about SASS or CSS and they need to contact me a lot and ask BUT now that I have set of a simple utility set of classes just for them they can build stuff and leave me alone. :)
Another useful methodology is Harry Robert’s ITCSS. There’s not a lot of information around about it, but a good overview is Lubos Kmetko’s article on xfive (https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/)
Thanks for the article comparing the different approaches.
I am partial to the Atomic Design methodology of CSS.
I recently developed my own Atomic design inspired CSS framework. This framework from born out of my need for a quick way to develop HTML prototypes without spending time on CSS development (that is why it uses a large section of utility CSS classes).
Please check it out on GitHub, and feel free to create branches or provide me with some feedback. I am in the process of developing some documentation.
https://github.com/celummis/AtomicAgnosticCSS
I’m missing ITCSS by Harry Roberts, too. Adopted it at a larger SCSS/SASS project a year ago and I actually like it very much
I personally use ITCSS for architecture with BEM for naming conventions along with some ideas for namespaces taken from SCMACSS. Works very well. All credits of course go to Harry Roberts. It is worth checking his articles and talks.
https://csswizardry.com/
http://rscss.io
Really readable markup (i.e. not BEM) and styles are pretty safe from leaking too much. Combined with CSS Modules scoping, it looks pretty good.