CSSNaming Conventions

Naming Conventions

Every CSS methodology eventually comes down to the same underlying question: what do you call a class? The naming philosophy you pick shapes how easy a codebase is to navigate, how safe it is to change a style without side effects elsewhere, and how quickly a new team member can guess what a class does just by reading its name.

A quick recap of the major philosophies

Methodology

Naming idea

BEM

Block__Element--Modifier — .card__title--large reads as "the title element, large modifier, of the card block." See BEM Methodology.

SMACSS

Categorizes rules (base, layout, module, state, theme) and prefixes accordingly, e.g. .is-active for state. See SMACSS.

Utility-first

Class names map to one property/value pair, e.g. .mt-4, .flex, .text-center — the name describes the CSS declaration, not the component. See Utility-First CSS.

Those pages go deep on each system individually. This page is about the naming principles that hold up regardless of which methodology (or combination of methodologies) a project settles on.

General principles that apply everywhere
  • Descriptive over cryptic.primary-nav beats .pn, even though the shorter name saves a few keystrokes; nobody has ever regretted a class name being too easy to understand six months later.

  • Consistent casing — kebab-case (.card-title, not .cardTitle or .card_title) is the CSS convention, matching CSS property names themselves (background-color, not backgroundColor). Pick one case style project-wide and never mix them.

  • Semantic over presentational — name what something is or does, not what it currently looks like. A name describing appearance breaks the moment the appearance changes.

  • Predictable, not clever — a newcomer should be able to guess related class names once they have seen a few; avoid one-off naming schemes that only make sense with tribal knowledge.

  • Scoped enough to avoid collisions — a name like .title alone is far too generic for a large codebase; some namespacing (a component prefix, a BEM block, a CSS Module) keeps it safe.

Presentational names age badly

The classic cautionary example is naming something after how it currently looks rather than what it communicates. It works fine on day one, and then breaks down the first time a designer changes a color:

HTML
<!-- Presentational: the name IS the current appearance -->
<p class="red-text">Payment failed. Please try again.</p>

<style>
  .red-text {
    color: #c0392b;
    font-weight: 600;
  }
</style>
If the design system later changes error messaging to use orange instead of red, every template using .red-text now has a class name that actively lies about what it renders. Worse, if .red-text also happens to get reused on something unrelated that just wants red text for a different reason, changing the error color changes that unrelated thing too.

HTML
<!-- Semantic: the name describes purpose, not appearance -->
<p class="error-text">Payment failed. Please try again.</p>

<style>
  .error-text {
    color: #c0392b;
    font-weight: 600;
  }
</style>
Now the color can change freely — .error-text still means exactly what it meant before, and nothing describing a different concept accidentally shares the class.
A worked before/after example

HTML
<!-- Before: cryptic, presentational, inconsistent casing -->
<div class="Box1">
  <span class="bTxt">Free Shipping</span>
  <button class="btnBlue">Shop Now</button>
</div>

<!-- After: descriptive, semantic, consistent kebab-case -->
<div class="promo-banner">
  <span class="promo-banner__label">Free Shipping</span>
  <button class="promo-banner__cta">Shop Now</button>
</div>

The "after" version borrows BEM's block/element separator, but the underlying wins are more basic than BEM itself: every name now reads as English, every name uses the same casing, and nothing describes a color or a specific pixel value that might not be true next redesign.

Pick a convention and write it down
The specific rules matter less than having them be explicit and applied consistently. A short project style guide (even five bullet points in a README) that says "kebab-case, BEM for components, semantic names only" prevents more real-world CSS pain than almost any individual naming choice within that guide.
Related pages
See BEM Methodology, SMACSS, and Utility-First CSS for the full systems these principles are drawn from.