DEV Community

Cover image for How I Moved a Step Closer to Clean CSS and How You Can Too (with the BEM Methodology)

How I Moved a Step Closer to Clean CSS and How You Can Too (with the BEM Methodology)

Gabe Romualdo on December 04, 2019

Around one and a half years ago, I was young, I was fairly new to building websites. At the time, I was mainly writing static HTML and CSS sites an...
Collapse
 
codeposse profile image
T.Hunold

Bloated
Extraneous
Markup

Collapse
 
perpetual_education profile image
perpetual . education

Yikes! "Cleaner" CSS but now the markup is horrendous. We tried B.E.M. on a few projects 5 years ago - and felt like it was really bad for everyone involved. It actively fights the Cascade... which is the best thing about CSS. It's like choosing not to use classes in OOP. 'Utility CSS' seems just as bad. We took a look at Tailwind, but just look at this markup: codepen.io/sheriffderek/pen/QWwyJmB - and that's not even with JS framework attributes and templating stuff. Under the hood, we're still adding little modular groups of rules - but we add them in the CSS instead of the HTML. What do you think about that style?

Collapse
 
gaberomualdo profile image
Gabe Romualdo • Edited

I think you bring up a great point in that BEM does actively go against the cascade. I think the main reason for this is that the cascade presents serious problems with CSS selector specificity.

Take this example, with a paragraph element inside a div:

<div id="container" class="div" style="color: green;">
  <p>Example Text</p>
</div>
#container { color: red; }
.div p { color: white; }
.div > p:not(:hover) { color: blue; }
div.div { color: purple !important; }

In this example, what color with the example text appear? To know this, you would have to understand specific intricacies of how CSS specificity and styles are actually calculated, which can be really hard to understand and interpret while actually writing your stylesheets.

This is a problem with the cascade which can quickly make CSS extremely confusing for less-experienced developers. BEM fixes all of this by eliminating specificity altogether, and showing specificity in the actual element classnames.

Of course, as you mentioned, BEM does make for less clean markup, but for me, that is a sacrifice I was willing to make for cleaner stylesheets.

As for using Tailwind and other utility CSS frameworks, I haven't ever tried using utility CSS yet. I enjoy writing my own stylesheets myself, but I understand that utility CSS can be really useful for writing CSS quickly and effectively.

Using a modular CSS system with different files and folders is great in my opinion, and is another way to write cleaner CSS. For this, I would suggest looking into various conventions for folder structures and systems for splitting up your styles. I use SASS as a precompiler, and I personally use these guidelines for most of my sites.

Thanks so much for reading!

— Gabriel

Collapse
 
perpetual_education profile image
perpetual . education • Edited

I each their own! : ) We'll be sticking with the markup and CSS that is most easily read by humans. We liked where this was going: maintainablecss.com

In any language - you can write it in a way that makes it harder to use... but - we just figure - we'll write it in a way that's easy to use. That works for us.

Thread Thread
 
squidbe profile image
squidbe • Edited

In any language - you can write it in a way that makes it harder to use... but - we just figure - we'll write it in a way that's easy to use.

And that's really the fundamental point. I feel like BEM (as well as some other CSS methodologies) adds lots of overhead to handle a worst case scenario which should be easily avoidable. After more than 15 years of writing CSS for many different scenarios, I can safely say I never worked on a project that became unmanageable to the point of actually needing something as heavy-handed as BEM (and I was on a team that used BEM for a couple of years). It appears to me that many of the struggles people seem to have WRT the CSS cascade and/or inheritance are based on either a misunderstanding of those concepts or an unwillingness to just think a little bit more about what they're doing. I would never write CSS like the example above (div p, div > p:not(:hover), div.div), and I wouldn't approve a commit where a teammate wrote that (and I'd ensure my team understood what a bad idea it is to use super generic selectors... and class names which are also tag names).

I've worked on large projects where many engineers touched the code, and it doesn't take more than following some simple best practices (e.g., not creating rules with more than two selectors) and a simple code search (which I still did when using BEM) to see whether your new rule would break something else.

So, indeed, to each their own.

Thread Thread
 
perpetual_education profile image
perpetual . education

YES. Clearly - there is a gap in understanding on these fronts. We're happy to demonstrate any situation anyone can think up. Glad we're not alone in this. We only have 10 years under our belt - and still wonder if we're missing something - so, it's lovely to hear from someone with 15 years.

Thread Thread
 
perpetual_education profile image
perpetual . education

PS - that code example - was more insane than we could ever come up with, so - the OP is clearly gifted in that manner.

Collapse
 
andrewsmith289 profile image
Andrew Smith

"In this example, what color with the example text appear? To know this, you would have to understand specific intricacies of how CSS specificity and styles are actually calculated,"

You should understand CSS specificity and how styles are calculated, not rely on a methodology that breaks the cascade because you don't.

Collapse
 
tobiobeck profile image
Tobi Obeck

You can extract tailwind CSS components with @apply as can be read here
or watched in a screencast here. This would at least move the verbose classes out of the markup.

Collapse
 
phiter profile image
Phiter Fernandes

I don't think I'd use Tailwind on a plain HTML+CSS site.
It is great for components though. I use Vue in most projects nowadays, and Tailwind's utility classes are used only once in the components you make.

Want a card? Make a functional card component with all the classes needed to compose a card component. Then, just use that.

If you don't want to mess up the HTML, you can extract the component with @apply in the style section of the component and use that instead.

Collapse
 
perpetual_education profile image
perpetual . education

We're usually working with Ember or Vue or WordPress for larger sites - and everything is a component. We don't have any room for a new toolbox of classes to fiddle around with. We're pretty happy with our workflow, but - we always check things out and give them a spin. : ) It all just reminds us of the "pull-left" years. again... "Yikes!"

Collapse
 
kamalhm profile image
Kamal

BEM was great but I'm all for utility css now

Collapse
 
cedricgourville profile image
Cédric Gourville

Hey great post.
A short time ago I was using BEM. and since then I have just discovered CSS modules. You should take a look

Collapse
 
squidbe profile image
squidbe • Edited

Yup. CSS modules basically do what shadow DOM does without the need for heavy polyfills or clunky syntax. What I love about Vue is that you get this behavior for free. Just add the "scoped" attribute to your component's style block, and Vue takes care of the hash for you. After 2 years of BEM and utility CSS (I was forced to use both at the same time), I'm loving Vue's built-in CSS module behavior.

But whichever way you do CSS modules, they're great because you don't have to worry about the rigidity and verbosity of BEM or the "unsemanticness" of utility CSS (I much prefer a class name like "date-widget" to a string of class names like "p-4px align-left color-red-8 [more class names that describe style instead of function]".

Collapse
 
cedricgourville profile image
Cédric Gourville

We agree on this point.
And your html too, is more readable, in my opinion

Collapse
 
giacomocerquone profile image
Giacomo Cerquone

I honestly do feel that BEM appeared some time ago to solve problems when web developing was done in a different way and when there were indeed many gotchas when applying style from a global perspective.

We can always learn something from BEM, being a guideline and not a technology, but in a react app, or any other present technology and so vanilla js too, we must strive to use solutions that scope the css to the component.

Another important thing is the abolition, if you will, of css classes in favour of components. Basically this is what I teach: when you are using again and again a class, nowadays, what you're doing without knowing it, is defining a reusable component.
So you remove the css class and you use a component that is styled in any way you want in a single part of the project. In this way you have a single point responsibld for the way your component looks (both markup and style).

Collapse
 
bayuangora profile image
Bayu Angora

I use minimal CSS that less than 500 lines for my website. And I separate my main CSS from my home CSS, because I use dark mode for inner page only.

Collapse
 
gaberomualdo profile image
Gabe Romualdo • Edited

For me, I've found BEM most useful in bigger sites with many pages, features, components, etc. The main advantage of BEM I've found is that it is a convention, which means it is very predictable. Being predictable means that other devs can easily migrate to your project and other projects using BEM by just learning the convention. It also means you can understand other devs code and CSS more easily (assuming they are using BEM as well).

I think my story in this post of my political aggregator website is a good example, in that the CSS in that site quickly became confusing as I added so many pages and DOM manipulation and the like. BEM would have likely fixed all of the problems I was having, made the site much more readable by other devs.

Again, of course all of this is just my view and opinion, and I definitely think it's great to use simpler, less-long and tedious classnames for smaller projects like your site. Thank you for reading!

— Gabriel