SO I have a problem with OOCSS. It is supposed to be more portable but compared to how I usually do things, I'm finding it less so.
My example:
I have a widget testimonial. In the main content body (which has a white background) the testimonial has a black font. But in the footer (which has a blue background) the testimonial needs a white font.
Before OOCSS, I would do something like this:
#main-content .testominial {
color: #000000;
}
#footer .testominial {
color: #FFFFFF;
}
With this "old" approach, I could drag my widget from the content area to the footer and the colours would simply work - I wouldn't need to change my CSS or DOM classes of the widget.
With the new OOCSS/BEM, I am NOT supposed to couple the .testimonial class to the ID (or to the location), but rather I should subclass it like so:
.testominial {
color: #000000;
}
.testominial--footer {
color: #FFFFFF;
}
The problem with this is that I can no longer drag my testimonial from the content area to the footer without going into the DOM and changing the classes on the testimonial widget - It is LESS portable as it requires manual intervention by a developer; whereas before an editor could just drag it and the styling was automatic.
Am I missing something? There seems to be no solid real-world examples out there?
If you "drag" the element
.testominial
from the container.main-content
to the container.main-footer
, that is you change the DOM. So you can also update the modifier in the CSS classes, there is no additional cost.The purpose of BEM is to make CSS classes reusable. The following modifiers can be reused in various environments.
CSS:
HTML:
With the old approach, you'll have to change the CSS code each time you need a new block
.testominial
in a new container. HTML and CSS are strongly coupled, and some CSS code will be duplicated.With the BEM approach, you'll have to add some CSS code each time the designer will add a new variation of the block appearance. HTML and CSS are less coupled, and CSS is better reused.
You need to consider dropping the
testimonial
naming as well as thefooter
.Consider this example:
In the example the classes are completely independent of their page context. The result is that the classes are completely re-usable. Any box on the page can take the classes above and expect to be styled exactly as defined.
For example, you could have:
Now when the designer comes back and tweaks the padding of the standout boxes you can go directly to those styles and tweak them, confident that the only areas that will be effected will be the areas that have those classes in the HTML.
Also, when you decide to move
.primary-box--reduced
from the<header>
into the menu bar that sits above it, or into the footer, you can be confident that the styles will come along, completely.When you need another element somewhere, perhaps a
primary-box--standout
, or just a defaultprimary-box
in the header, you just create it and add the classes, they styles will follow completely.You'll never inherit unexpected styles either.
This is very much a real world example, a site I built recently was almost all built like this, I say almost all because I'm still learning, but I can guarantee the bits I had the least trouble with on a fast-moving project with very fluid designs were the ones with non-specific context.
What's important is the lack of context. In the first example,
.testimonial--footer
is very context dependent, you really need to use it on testimonials in the footer only.And as if by magic CSS Wizardry cover this exact topic
EDIT: I added this example to help with a comment made on my answer. This isn't BEM, or OOCSS, though it is a bit closer to the SMACSS approach. It's how I tackle problems with css and is a hybrid BEM / SMACSS approach:
Loaded in order:
.primary-box
.header
or.call-to-action
.about-us
or.contact
Each file gets more and more specific, while simultaneously building more complex and modules. Building on the examples above and hopefully helping the OP, you could see styles like:
which would over-ride the module styles using a more specific nested class notation. Please note, I would still avoid using a class name like
.header
-.banner-standout
would be better as it's re-usable anywhere without confusionNext, you could even see:
I find this works very well in real projects for context while retaining the context free power of BEM, though I would also urge as much as possible to push up this chain into the modules. Life is easier if I recognise a new generic page section or module and re-organise the naming and files appropriately. In a project where the code has been refactored with care I have nothing in page files.