For the last couple of months I’ve been talking a lot about giving our css best practices a refresh and along the way have looked at approaches such as OOCSS, SMACSS, and DRY CSS. They all have some common underlying principles, one of which is the separation of structure and presentation.
We’ve all had this goal for years, but our practices haven’t really achieved it. Instead of decoupling our html and css we’ve been locking them ever tighter and making them more and more dependent on each other. I apologize if you’re getting tired of hearing me talk about coupling, but I think it’s a very important concept to understand if you want to develop scalable and maintainable websites.
Just last week Jonathan Snook, creator of SMACSS, brought up the very same topic on Smashing Magazine. I want to touch on a few of the points he made and then give a quick walk through of yet another method (BEM) with similar goals to the ones we’ve been talking about.
Decoupling HTML and CSS
Ideally we’d like to be able to completely rewrite our html or css without touching the other. That’s unlikely to happen all the time. There will often be a need to changes one after changing the other. However the less dependent our html and css are on each other, the better.
Using OOCSS we reduce coupling by dropping descendent selectors in favor of classes. With a DRY CSS approach we’re also using classes, but here the magic is based more on how we organize our css around stylistic groups. SMACSS falls somewhere in between these approaches.
All agree we should move away from location based selectors as tying css selectors to a specific html structure leads to greater difficulty in changing either html or css. Inevitably we’re left managing specificity.
Jonathan Snook refers to this as the depth of applicability or in his words, “the depth at which a particular rule set impacts the elements around it.”
For example consider the following code for a relatively simple navigation bar with a single drop down.
If we were to write some css targeting the link in the drop down ( #nav li a ), the depth of applicability is 5. Even though we didn’t specifically mention every element along the way we’ve moved through ul#nav to li to ul to li to a, or 5 levels of html structure.
That’s too much and it also affects both the top level links and secondary links in the drop down. Jonathan offers two ways to reduce the depth of applicability
- Child selectors — using #nav > li > a limits the scope to the top level links
- Class selectors — is ultimately the better approach as it’s not dependent on html structure at all
Jonathan offers some additional explanation and examples in the Smashing Magazine article, which is worth a read if you’ve yet to see it.
The key is in seeing that many of the selectors we’ve been using over the years are coupling our html and css ever tighter. The debate is still ongoing as to the best way to decouple things, though hopefully you agree there’s a need for decoupling.
BEM — Block, Element, Modifier
The BEM approach to developing websites comes from the developers at Yandex. It has similar goals to the approaches we’ve seen before.
- Quick development
- Team efficiency
- Code reuse
Blocks and Elements
Under BEM a block is it’s own independent entity. Blocks can be simple or complex and they can contain other blocks. There’s something familiar in this as every html element is displayed as a box or block of some kind.
At the highest level of a design, your blocks might be your header block, footer block, main content block, and sidebar block. Your header would likely include several blocks inside such as one for your logo and tagline, another for a navigation bar, and maybe another making up a search field and button.
Elements are parts of blocks. They perform certain functions within the block and they’re context dependent. Take an element outside its block and it no longer makes sense. For example a search block might be made up of 2 elements.
- Input field
Removing one doesn’t make sense as the block would no longer function correctly.
Together blocks and elements are arranged in your design to form your page layout. Elements are arranged inside blocks and blocks are arranged inside other blocks working up to the outermost container blocks that shape the page as a whole.
Blocks and elements should have keywords (names) associated with them. The only way the same name or keyword is reused is when the same block or element is being reused. Blocks must be independent of each other to allow for arbitrary placement within the design. We want to be able to take our search block and easily move it from the top right in the header to the middle of the sidebar for example.
This leads to 3 guidelines for writing css:
- Blocks should have unique names, which become classes
- HTML elements should not be used in css selectors since they aren’t context-free
- Cascading selectors for several blocks should be avoided
Here again it’s the use of classes that aims to solve the problem of coupling. We’re also encouraged to avoid location based selectors (context dependent) to help decouple our code.
What happens when you have a block like a search input and button and you want to add another to the page that looks similar, though not exactly like the first? This is where modifiers come in. Modifiers help us create similar though different blocks from already existing blocks.
A modifier is a property of a block or an element that alters its look or behavior. A modifier has a name and a value. Several modifiers can be used at once.
Typically a modifier will be an additional css class you would add to an element. An example I’m sure you’ve come across is highlighting the currently selected menu item so it stands out from the rest of the menu items. To achieve this you probably created css similar to the following.
You’d then added class=”current” to the currently selected menu item. The class modifies one element inside your navigation block.
The idea of seeing a web page as elements within blocks within blocks is an easy one to grasp and probably how many of us already view the pages we develop. I certainly have, as you can see in a couple of posts I wrote for Onextrapixel a couple years back.
- Part 1: How to Turn a Design Image Into a Working Web Page
- Part 2: How to Turn a Design Image Into a Working Web Page
Most of these methods are similar in their underlying goals and principles, which is the main thing to be paying attention to. You’ll likely pick and choose techniques across some of these approaches depending upon the specific problem in front of you as opposed to following any one entirely.
It’s the underlying principles like decoupling html and css that are more important. It’s the idea of reducing location based selectors, mostly likely through a greater use of classes that you should be thinking about. See how each approach attempts to solve this and decide which makes the most sense for you.
If you’re getting tired of these posts please let me know. I realize I’ve been offering a lot about this same basic concept for awhile and perhaps the message has long since gotten across. If you are enjoying these posts and some of the methods I’ve been pointing to, let me know as well. There are more approaches out there with similar goals in mind that I could cover.
Download a free sample from my book, Design Fundamentals.
Are you concerned about “classitis” and other similar criticisms that web developers have dealt with in the past?
“You may have classitis. The way to tell for sure is to dive into the CSS: If the styles are predominately classes (i.e. are “.className”) with ancestor selectors being few and far between, then you have classitis.” – http://ow.ly/aF3OD
No, I’m not concerned about classitis. The whole point of all these new approaches to writing css is that much of what we’ve thought for years and how we’ve been writing css is wrong, including the idea that classitis is bad and something to avoid.
There’s a lot of thought in the last couple of years suggesting we’d be better off using more classes and not less.
Thanks for your article.
I’m trying to make my mind BEMfull at the monent. And your point of view is very useful. Thanks!
Thanks Alex. I’m glad I could help.
Thanks Steven. Please do keep writing these posts. I think this decoupling / modular / object oriented / context-free approach to html / css design is essential and been (surprisingly?) overlooked too long. For me it is about developing to a design as quickly and efficiently as possible but with maintainable scalable code. Even better the idea of designing in the browser becomes far more real and viable. All this is great stuff, is the future and concur your passion for it.
+ Am digging your site finding lots of good stuff. Cheers.
Thanks Wayne. I’ve actually been collecting more thoughts and ideas about modular design and development for future posts. I’m not quite sure yet what those posts will be about yet, but the ideas are beginning to grow.
I agree with you about being able to develop quickly and efficiently while still having a maintainable codebase. Right now I’m leaning toward preprocessors as the best way to make that happen, but I still need to put them to more practical use to really decide.
Thanks for the compliment. I’m glad you’re liking what you find here.
Actually, I am in a project as the front-end developer. While working on the CSS of the app, I have noticed lots of things that I didnt know were so wrong.
I was taugh not to fall into classitis and I have been avoiding using it, but somehow, not using classes had been limiting the way I style pages. And I do not like to use those huge descendant selectors. They are hard and complicated.
I have read about SMACSS, OOCSS and now BEM. It is what I was looking for. Best thing, I do not need to use anything special (though it is posible) like SASS or LESS.
I feel actually the same.
BEM was dried to use for Frontend. ATM we trying to use it as backend modules and it’s great! Methodology is now so good for backend as it can be but still it’s great.
And I said it again — BEM is OOM.
Btw we still using preprocessor for CSS with BEM. We writing stylus files for blocks instead of pure css, but it’s possible to use anything else like sass, less, or anything else.
Thanks Steven! This is an excellent writeup on BEM. How does your folder structure look under this paradigm? Like the one you explained in the SMACSS article?
Thanks Alberto. Sorry for taking a few days to reply. You can use any folder structure you want with BEM. The main thing about BEM is thinking about things in terms of blocks, elements, and modifiers, and then following a naming convention for each. Any directory structure you want to use should work.
Hola. No entendí mucho el sistema de BEM. Cómo se puede implementar este método? Que son los modificadores?
It’s been a long time since I wrote the post, but I think BEM was mostly a naming convention. If you want to use it I would go directly to the source getbem.com/