DEV Community

Alex Dimitrov
Alex Dimitrov

Posted on • Edited on

CSS Naming Conventions

If you are new to development as a whole, naming conventions might be something you've come across as a "best practice" and tips like "Pick one and follow it" were scattered across books, articles and tutorials.

I won't spend too much time in the what it is, but instead on the why. To be brief, a naming convention is a set of rules on naming things. Such rules might be "Always write with lower case" and "If there are two words, separate with a dash". Some might be more complex like "If a function returns a value, write get infront of it".

In CSS, there are such naming conventions as well, and they solve a problem, which exists due to the nature of how CSS is parsed by the browser.

The problem: You don't really have much of a scope control. Of course, you have at-rules @, that act as a block scope, but not much else. And nesting rules isn't really scoping, not in CSS. Because both examples: .parent {} and .parent .children {} sit in the same global scope. Yes, of course, .children's styles would be applied only if there is a .parent up the tree, but both rules are written in the same level, both are in the same file.

A detour to JavaScript-land:

To illustrate a difference, let's look into how CSS is scoped in the JavaScript world with libraries/frameworks/tools like CSS in JS. There, you can write your CSS again in the same level, but it is truely scoped in the component. It generates unreadable unique classes like .ts7hf which is only available to the component you defined it to. The tool manages the scope for you, you don't have to worry about leaking CSS to other components.

Back to CSS

In CSS, all your code goes into one file. Well, that is not required, **but in the common case that's how it goes. You might bundle CSS files into one, or you might compile Sass files into one, in the end, most often it's the same file. And all rules inside sit **in the same scope. How do you then manage what is applied where, and ensure that no styles leak? By defining a set of rules that a developer must follow. To know and follow, because they are not kept in check by a tool.

First, let's see how a style can leak. In the example below, we define a very simple rule, where all h4 children of our About us page must be red.

.page-template-about-us h4 { color: red; }
Enter fullscreen mode Exit fullscreen mode

Then, in that about us page, we want to output a card component that happens to use the h4 tag for it's heading element:

<div class="card">
    <header class="card-header">
        <h4 class="title">Hello world!</h4>
    </header>
</div>
Enter fullscreen mode Exit fullscreen mode

So now, we want all card elements to have tomato headings. We are doing wild design work here, don't judge!

So, we style it like this:

.card h4 { color: tomato }
Enter fullscreen mode Exit fullscreen mode

Some more experienced developers will already notice at least 4-5 problems with the examples above.

Which color would the headnig end up with? The correct answer is one: It depends on the order of the rules, because both the first and the second styling snippet contain the same Specificity (part of the CSS fundamentals).

The h4 tag will apply the first color defined in the stylesheet, and then get overwritten by the next one, because it has the same level of specificity. The problem here is that you have to worry about the order of your rules. As stated before, they all sit in the global scope, so anything coule be inherited or applyed from any place. Yes, even that small file someone created 6 years ago that is still bundled and you are afraid to delete, because you don't know what elements it styles.

Fix problems by following rules.

The problem above happens when no rules are followed from the start of the project. Fixing that is a real struggle and requires a lot of dev time, QA-ing and risk of breaking the app/website. So it's rarely suggested. Instead, slowly rewrite parts of the website with new styles. There will be another post on that topic exactly.

Don't target pure HTML tags with large-scale selectors.

The example above uses a class on the body element. All HTML elements H4 inside will have the style applied. With that, you only create problems for yourself. Instead, you should better understand the business goal that needs that page to style it's h4 tags and see if there is a better solution.

✅ Style tags by class name as often as possible

In the .card element, you should select the heading element by it's class selector. Most often, it's possible that it's HTML tag could change at some point and that change should be then reflected in CSS.

✅ Follow a naming convention for your classes

The example above uses .title for heading. Yes, it makes sense to name it title, but it's too generic and it isn't scoped to the .card element. A simple change like writing .card-title would increase readability and reduce the chances of styles clashing. Think of it this way — how many components on your app/website would have a title of some sorts? Would you feel safe, naming all of them with the same class? How can you be certain no styles would leak?

What naming conventions exist?

Alright, so we saw some problems that exist because we don't set rules or think about how everything works together. All great, but the example rules above are too few and don't cover all cases, right? The good thing is that people already came up with rules that you can take for free and follow. They work both on small and large scale applications. Which one is the best for you is maybe a bit trickier to decide, so the best thing you can do is build the same app using different conventions and see for yourself.

BEM — Block Element Modifier (documentation)

Maybe the most populer one that comes to mind is BEM. It is easy to understand, the concept is straightforward and just reading a class could tell you about what's going on (when written well of course).

OOCSS — Object Orientated CSS (Guide)

The idea of separating visuals from structural styles is baked into the Object Orientated CSS approach. It focuses a lot less on how you name your classes and more on the idea of what they represent.

SMACSS — Scalable and Modular Architecture for CSS (website)

SMACSS focses more on organizing your styles — placing each selector in it's proper category like Base, Layout, Module etc. It's similar to the categorization done in the previous post in the series: The Component Types in Front-End Development. I have personally taken a ton of the practices in SMACSS in my day-to-day work like the state management (is prefix) or the avoidance of element selectors among many others.

ITCSS — Inverted Triangle CSS (article)

Similar to the Component types, it's a method of grouping your styles based on the context and their purpose. It goes from the most broad selectors to the most specific ones. The article above is a very good read and following that line of thought is always helpful in your code structure.

AMCSS — Attribute modules for CSS (website)

It's a very interesting approach that takes selecting elements to a new place — ignore the Class attribute and use all the custom Data attributes you can add to an HTML element. Instead of writing .button, why not do [am-Button] ? What I liked here is that you can visually differenciate different types of classes. A button can have it's core .button class, but it can also be a js-toggle-modal, which should be maintaining some interactivity. Both are very different, but also applied to the same attribute "class". With AMCSS, this can be separated visually. However, I am kinda iffy on the look of the selectors.

Your naming convention

All of the above are some of the more popular one other developers came up with. But the thing is that you will probably find as many naming conventions as many developers there are. Some will dislike an idea of BEM, so they will skip it and in it's place take something from SMACSS. Some will like the idea of ITCSS's separation, and appliy it with the AMCSS attributes.

I personally love the BEM idea, but it doesn't match the WordPress standard of writing classes with lower case, separated with a single dash. And it's fine, because I can follow the same thinking of BEM, but without the __ and -- as separators. I could also use the .js- and .is- prefixes too from other approaches. And the cool thing - it works, it makes sense and most importantly it's consistent.

Which is the final takeaway from this — do whatever works for you, but do it consistently across the project. Ideally, across all your projects. That way, all developers will expect where to find things and how to write styles without looking at long documentations and set of rules.

Read next: Two tips to keep your CSS simpler

Top comments (0)