CSS Naming Conventions: BEM, OOCSS, SMACSS Compared

6 min read

Naming CSS classes might seem trivial, but in large codebases it becomes one of the most important architectural decisions. A good naming convention prevents specificity wars, reduces naming collisions, and makes stylesheets self-documenting.

Why CSS Naming Matters

CSS has a global namespace. Every class name is available everywhere, and specificity rules determine which styles win. Without a naming convention, teams inevitably create conflicts: two developers both name their class .card, and one overwrites the other.

BEM (Block Element Modifier)

BEM is the most widely adopted CSS naming convention. It uses a structured pattern:

.block {}
.block__element {}
.block--modifier {}

/* Example */
.card {}
.card__title {}
.card__image {}
.card--featured {}
.card__title--large {}

BEM Rules

  • Block: A standalone component. Named in kebab-case: .search-form, .nav-bar.
  • Element: A part of a block that has no standalone meaning. Double underscore separator: .search-form__input.
  • Modifier: A variant or state of a block/element. Double hyphen separator: .search-form--dark.

BEM Benefits

  • Self-documenting: .card__title--highlighted tells you exactly what it is
  • Low specificity: everything is a single class selector
  • No naming collisions: the block name scopes everything
  • Framework-agnostic: works with any tech stack

OOCSS (Object-Oriented CSS)

OOCSS separates structure from skin and container from content:

/* Structure */
.media { display: flex; align-items: start; }
.media__body { flex: 1; }

/* Skin */
.theme-dark { background: #333; color: #fff; }
.theme-light { background: #fff; color: #333; }

OOCSS creates highly reusable utility objects but can lead to many classes on a single HTML element.

SMACSS (Scalable and Modular Architecture)

SMACSS categorizes CSS rules into five types with prefixes:

CategoryPrefixExample
Basenonehtml, body, h1
Layoutl-.l-sidebar
Modulenone.card
Stateis-.is-active
Themet-.t-dark

CSS Modules and CSS-in-JS

Modern frameworks like React offer alternatives that solve naming collisions at the tooling level:

  • CSS Modules: Automatically scopes class names. You write .title, the build tool outputs .Card_title_x7kd2. Use camelCase for class names since they become JavaScript properties.
  • Tailwind CSS: Uses utility classes, eliminating custom naming entirely.
  • styled-components / Emotion: CSS-in-JS with auto-generated class names.

Which Should You Choose?

ApproachBest For
BEMTraditional CSS, multi-developer teams, CMS themes
CSS ModulesReact/Vue/Svelte component-based projects
TailwindRapid prototyping, utility-first workflows
SMACSSLarge legacy codebases needing organization

Convert Your Class Names

CSS classes always use kebab-case. Convert from other formats with our kebab-case converter. If you need camelCase for CSS Modules, try the camelCase converter or the case converter hub.