Some time ago (a few years to be more accurate), I had an epiphany, if I may embellish it, or in a common Uruguayan idiom: me cayó la ficha.
I realized the following
Writing CSS can be really simple if we only focus on changing an element’s width, height or background color. Like a painter coloring a drawing, if we need to change the color we need to start over, change the brush and use the correct color.
It might sound silly, but when given some thought, doing the same in CSS involves only to copy code and change the background property. The same can be said for hundreds of examples.
What happens when we’d like to write our CSS with the goals that the code has to be maintainable, scalable, predictable, reusable, etc?
If we want to avoid the impossible task of maintaining spaguetti code, we may find salvation in one or many Holy Grail solutions that can be found online. It sounds like an hyperbole but in the end they might save us from the nightmare of refactoring such code.
We’ll show here 3 methodologies:
- OOCSS (Object Oriented)
- SMACSS (Scalable Modular Architecture)
- BEM (Block, Element, Modifier)
It should be noted that these are not W3C defined standards. This means they are not absolute laws on how code must be written but general practices that we can follow.
OOCSS
“The main premise is to follow object-oriented programming paradigms in regards to code reuse. The goal of OOCSS is simple: to build optimized code that allows us to quickly and easily improve on it”.
– ID:
Usage of ID should be exclusively relegated to forms and in JS code. When writing CSS we should only use classes which allows us to easily reuse code when necessary.
– Properties
Since code reduction and reuse are the goals we need to pay extra attention to similar elements that have repeated properties. Ideally we should take those common properties and group them in a common class, with unique properties to each element in a new class.
SMACSS
More than a set of best practices, these can be considered an architecture, a guide for writing styles or even a philosophy created by Jonathan Snook.
It is basically a way to organize our CSS files in a project in order to improve maintainability, flexibility and the possibility of scalability in time. This is achieved by categorizing styles files. SMACSS defines 5 types of categories:
– Base files
These include base styles, normalization, typographies, etc.
– Module files
Modules are reusable independent components (This are called components in OOCSS. While in BEM they are known as blocks)
– State files
As the name implies, these are the state rules for the modules. Here is defined the look of each modules in each particular state.
– Layout files
These are styles that format our grid. For example: size of columns, etc.
– Theme files
These are related to the visual look of the site: sizes, shapes, colors, etc.
We invite the reader to research more on these two methodologies previously mentioned while now we’ll focus on BEM.
What is BEM?
It is a methodology with three fundamental rules to name and categorize CSS selectors in a strict, transparent and self-explanatory manner.
– Block
It is an independent entity. It can be seen as an object or module.
.block {}
– Element
It is a part of a block that serves a particular purpose. For example a title or a button.
.block__element {}
– Modifier
It handles the changes of look or behaviour of blocks or elements. For example the appearance of a menu when the status is active.
.block–modifier {}
Now let us continue with something more practical:
HTML
<div></div>
We can apply a bunch of CSS properties to this simple DIV in order to make it look how we like; however this does not mean we should put all eggs in one basket.
Let us do the following:
HMTL
<div class=”news”></div>
Inside our DIV we want to show news, but what if we would like to have different categories like Technology, Economy, Fashion, etc? What if each category must have its own unique look (color, backgrounds, sizes, etc)?
How should we accomplish this?
CSS
.news-technologies{…}
.news-economy{…}
.news-fashion{…}
If we do it this way, we will make it simple and easy for us, at least for the moment. But like I said, this is putting all eggs in one basket just because we can.
What if we think differently and try to implement BEM when styling our news?
I can be as simple as writing something like this:
CSS
.news{common properties…}
.news–technologies{…}
.news–economy{…}
.news–fashion{…}
HTML
<div class=”news news–technologies”></div>
<div class=”news news–economy”></div>
<div class=”news news–fashion”></div>
What we just did is create a block and a modifier
CSS
.news{ common properties …} /* Block */
.news–technologies{…} /* Modifier */
What if we’d like to add a new element inside our news DIV like for example a title?
We might write something like this:
CSS
.news__title {} /* Element */
HTML
<div class=”news news–technologies”>
<h1 class=”news__title”></h1>
</div>
Let us now summarize and try reach a conclusion. We may think a chance as small as this can not make a difference, but we need to see the forest from the trees.
Imagine a large website with hundreds of elements that need styling. What if you could modify each element or block depending on the situation, status or location in the page with the knowledge that any new feature can be solved by the creation of a new Modifier class, maximizing code reuse?
It is difficult to believe, right? But if you try to look beyond and understand the premises behind, you might find out that by using BEM (or OOCSS, or SMACSS) your world can become much better.
The conclusion I reached, in that, in my personal opinion, each paradigm has a bit of the others.
What if we could mix all premises and also use preprocessors (like CSS on steroids :D) like LESS, SASS or Stylus, taking them into the next level.
We can agree that the end result is only limited by our imagination, or rather by the scope of the project we are working on. We can now know that when the projects grows we can do the same, like friends walking side by side.
I can go on. Like I said, our limit is in the imagination.
Here are some examples on how to implement it:
CSS
.btn { display: inline-block; cursor: pointer; font-size: 14px; padding: 6px 12px; color: #ccc; text-decoration: none; } .btn--small { padding: 3px 8px; font-size: 12px; } .btn--medium { padding: 6px 15px; font-size: 14px; } .btn--large { padding: 8px 20px; font-size: 16px; } .btn--rounded { border-radius: 5px; } .btn--cancel { background: red; color: #fff; } .btn--active { background: blue; color: #fff; } .btn--ok{ background: green; color: #fff; }
HTML
<a href="#" class="btn btn--small btn--cancel btn--rounded">BUTTON</a> <a href="#" class="btn btn--medium btn--cancel btn--rounded">BUTTON</a> <a href="#" class="btn btn--large btn--cancel btn--rounded">BUTTON</a> <a href="#" class="btn btn--large btn--active btn--rounded">BUTTON</a> <a href="#" class="btn btn--large btn--ok">BUTTON</a>
Inspired by:
CSS Architecture, by Philip Walton (11/16/12)
MindBEMding – getting your head around BEM syntax, by Harry Roberts (1/25/13)
Posted in Software Development, Technologies