Notifications
Sign Up Sign In
Q&A

Styling with classes vs styling with CSS

+8
−1

I've noticed that a lot of sites have something like this going on:

<div class="has-margin-0 has-padding-4">
    <div>...</div>
    <div>...</div>
    ...
</div>
.has-margin-0 {
    margin: 0;
}
.has-padding-4 {
    padding: 4px;
}

I'm a beginner who's self taught / internet searched most of their HTML and CSS knowledge. Currently I use human readable class names and style those instead of this weird (to me) method of moving the styling to classes. However, the "style by classes" method seems to be pretty popular for some reason, and I'd like to know why.

What are the pros and cons of using that method?

Why should this post be closed?

0 comments

1 answer

+6
−0

This styling method is called "atomic classes".

The goal of those is to prevent writing repetitive and badly maintainable CSS. For example, we might want to have primary colored variants of buttons and notices. In non-atomic CSS we'd write something like this:

.button {}
.button.btn-primary {
    background-color: #314159;
}

.notice {}
.notice.notice-primary {
    background-color: #314159;
}

And if we had more components where the background might become primary colored, we'd have to repeat the rule even more. This violates the principle "DRY: Don't repeat yourself" and creates maintenance issues, because you might miss some of the situations if you were to change the primary color.

Granted, the maintainability isn't that much of an issue anymore if you use modern CSS3 variables, but there is still an DRY issue.

On the other hand, if you use atomic CSS, you can simplify the code to:

.button {}
.notice {}

.bg-primary {
    background-color: #314159;
}

Now we have a helper class (.bg-primary), that can be used everywhere where you want a primary color background. Without writing any further line of CSS. Even on our nice widget component, that – until now – didn't knew anything of primary backgrounds.

Furthermore, atomic classes allow you to simply change the styling of a component at the place where it is defined: in the HTML code for it. If you want to change the button color, just replace class="button bg-primary" with class="button bg-grey" and voilà.

While some might (and do) argue, that atomic CSS is, like inline CSS via style="", the worst crime against semantic HTML since the invention of <div>, there are some objective advantages over inlince CSS:

  • Specifity. Inline CSS has a very high specifity and is hardly overriden by CSS, unless you use !important. Atomic CSS OTOH has a very low specifity, because it's only basing on classes for element selection. This allows you to easily override it via most other selectors (attributes, IDs, selector chains, ...)
  • Flexibility. Inline CSS isn't very flexible. For example it isn't possible to react to hover/active/focus state or to use media queries. All of this is possible with atomic CSS, though.

Atomic CSS is also great for templating stuff and making "mockups", because you can create almost any style you want with just a few classes and without writing any CSS. If you were to use components, you'd have to write a lot of CSS only for that mocked up new component, which doesn't happen with Atomic CSS.

However, atomic CSS (at least when applied strictly) doesn't allow for reusable components. If you want a button, you'll always have to add .bg-primary .c-white .radius-3. While this might be okay for a button, it stops being trivial for complexer components (e.g. widgets or grids).

To mitigate that issue, many framework developers (including for example Bootstrap or Co-Design, the framework used by this very site) use a mix of classical component-based and atomic CSS. They provide often-used components (for example buttons, alerts or cards) and allow users to override the default styles with the atomic helper classes.

4 comments

Do note one major difference between what you're describing here and what OP describes in the question: your example class names are semantic, while OP's isn't. The example in the question is for class names that directly describe the property applied ("has-padding-4" gives a 4 px padding); your examples are for class names that describe intended usage ("bg-primary" presumably for some kind of "primary" element). I feel that your answer would be improved if you discussed this difference. ‭aCVn‭ 8 days ago

@aCVn huh? I don't really see a difference. From what I have seen (and used myself), many frameworks using the utility classes approach don't make padding-4 have a padding of 4px, but of 4 times a specific "padding" unit. Also, if you'd name your class bg-314159, you'd effectively lose the maintainability advantage IMO. So in this case, primary is a name for the color, as defined in the design system. Having a set of "design colors" is quite common in design frameworks AFAICT. ‭luap42‭ 7 days ago

@luap42 Maybe I simply read too much into it, but OP's examples seem to state the actual value of the property in the name of the style for that property. I know that relative dimensions is fairly common in CSS style names, where a "width-8" class makes something twice as wide as a "width-4" class does, which in turn is a little wider than a "width-3" class. In OP's second example that seems to apply only if the base padding is 1px. Just something I noted comparing the Q and your A. ‭aCVn‭ 5 days ago

I had the same thought as aCVn. The question seems to be about using human-readable class names vs cargo-cult application of atomic styling. ‭Peter Taylor‭ 5 days ago

Sign up to answer this question »