Simple naming convention that can keep you from CSS uncertainty problem

Easy and hard of CSS

CSS is easy. Yes, the point of CSS is let you style HTML with straightforward syntax. The hard part of CSS is hacks. Hacks let you do things that you want do but CSS not yet considered yet. For example, layout with float is a hack, that makes it hard and came so many grid frameworks.

Another real hard part is the naming of CSS selector. Because naming of CSS selector determines the scope of HTML elements that will apply to the rule. Also, a naming of CSS selector will effect specificity of a rule. If you don’t do it carefully, your stylesheet will end up in specificity war and doomed.

With the evolution of JavaScript tooling, now we have more tools came to solve CSS problems. The latest hotness it css-modules. It can guarantee your style will only apply to elements you want. But for those that don’t want to use JavaScript tools yet, I am going to share some simple naming rules to use in your project.

Uncertainty Problem

The everlasting problem when you write CSS rule is uncertainty problem. You are not sure your rule will affect element you don’t want to. For example, it is quite straightforward to use descendant selectors to limit style in a section.

.my-product .price { ... }
.my-product .quantity { ... }

Especially if you use Sass, it’s so easy to write.

.my-product {
.price { ... }
.quantity { ... }
}

Things work fine, until someone in your team, or even yourself, forget there is a .card .header rule, wrote another .header rule.

.price { ... }
/* far away */
.my-product {
.price { ... }
.quantity { ... }
}

Although .my-product .price have higher specificity, only rules that is duplicated will be overwritten, so you will see unwanted styles.

Solve with private class name

So lets add a underscore prefix to .price.

.price { ... }
/* far away */
.my-product {
._price { ... }
._quantity { ... }
}

The underscore prefix indicates this selector is private. You can only use it as a descendant selector, so you won’t get unwanted selector by accident anymore. So you may have a bunch of “private selector” that won’t affect each other.

.book {
._price { ... }
._quantity { ... }
}
.pc {
._price { ... }
._quantity { ... }
}
.mac {
._price { ... }
._quantity { ... }
}

This works quite well until you have complicated structure like this:

<div class="products">
<div class="_price">
<div class="product">
<div class="_price">
</div>
</div>
<div>

Style of .product ._price will be affected by .products ._price. Then you will need to use more robust naming methodologies like BEM, SMACSS to make sure you style is more robust and explicit. But this never happened to me. Because I only use “private selector” only on styles that are not yet ready to abstract to component yet and the private class names is usually content related.

Hope this little naming convention helps you have more confident in styling, even when its not a “component” yet.

Show your support

Clapping shows how much you appreciated Art Pai’s story.