Frontend Development 15 min read

Mastering CSS Class Naming: From Chaos to BEM and Beyond

This article explores the challenges of CSS class naming, traces its evolution from chaotic practices through atomic and modular approaches to the widely adopted BEM methodology, and provides practical rules, keyword lists, and code examples for creating clear, maintainable, and conflict‑free class structures.

Tencent IMWeb Frontend Team
Tencent IMWeb Frontend Team
Tencent IMWeb Frontend Team
Mastering CSS Class Naming: From Chaos to BEM and Beyond

Anyone who writes CSS has faced the dilemma of naming classes that are both descriptive and conflict‑free.

Should a class be generic or specific?

How can you know if a class is used elsewhere?

Typical approaches lead to messy, mixed‑language names that work only because the page renders, but they cause maintenance headaches when conflicts arise.

Why Class Naming Is Hard

Unlike IDs, classes are meant to be reusable, yet they must avoid style collisions. Reusability favors simple, abstract names, while conflict avoidance pushes for uniqueness. BEM solves this by making classes effectively unique; other strategies include scoping with parent elements, adding modifier classes, or separating styles into different files per page.

<code>// BEM
.imgslide__item__img{}

// Parent‑scoped
.imgslide .item .img{}

// Modifier class
.img{}
.img--special{}

// Different pages, different files
/* a.html & a.css */
.img{}
/* b.html & b.css */
.img{}
</code>

Class naming has evolved through several stages:

Evolution Stages

Chaos: No rules, random names, often mixing Chinese and English.

Atomic: Lots of tiny utility classes combined to form a layout.

Modular: Prefixes like

.l-

(layout),

.g-

(global),

.m-

(module) to indicate purpose.

BEM: Block‑Element‑Modifier pattern that enforces a clear hierarchy.

Chaos Stage

Early HTML projects used ad‑hoc names such as

h1.title

,

div.hd-s

, or

.red{color:red;font-size:14px;}

, which often mixed semantics and style.

Atomic Stage

Utility classes like

.fl

,

.pr

,

.fs12

are combined in HTML (e.g.,

div.fs12.fl.pr.tac

), but this leads to long class lists and makes maintenance difficult, especially in front‑back separation scenarios.

Modular Stage

Prefixes indicate function:

.l-960

,

.g-red

,

.m-login

. While clearer, the growing number of prefixes can become unwieldy.

BEM Stage

BEM’s long, descriptive class names (

.block__element--modifier

) virtually eliminate collisions, though they can be verbose.

Learning From Others

Choose the naming style that fits the project: simple names for quick demos, atomic utilities for tiny styles, modular prefixes for larger structures, and BEM for robust, scalable codebases.

Common Class Keywords

Layout: header, footer, container, main, content, aside, page, section

Wrapper: wrap, inner

Block: region, block, box

Structure: hd, bd, ft, top, bottom, left, right, middle, col, row, grid, span

List: list, item, field

State: active, current, checked, hover, fail, success, warn, error, on, off

Navigation: nav, prev, next, breadcrumb, paging, first, last

Interaction: tips, alert, modal, pop, panel, tabs, accordion, slide, scroll, overlay

Icon: icon-

...and many others.

Simple Naming Rules

Use hyphens to separate words, e.g.,

.item-img

.

Two hyphens denote a modifier, e.g.,

.item-img--small

.

State classes are plain words like

.active

,

.checked

.

Icon classes start with

icon-

, e.g.,

.icon-font.i-name

.

Prefix JavaScript‑hook classes with

js-

.

Limit combined classes to four.

Practical Example

Layout skeleton:

<code>header.header > .inner-center
section.section-feature > .inner-center
section.section-main > .inner-center
section.section-postscript > .inner-center
footer.footer > .inner-center
</code>

When the same structure appears elsewhere, add a modifier prefix, e.g.,

.block-hd

,

.modal-hd

,

.article-hd

. For titles, use

.page-tt

or

.block-tt

. To specialize a class, either extend the name (

.page-tt--user

) or add a modifier class (

.page-tt.page-tt--user

) or scope it with a parent (

.page-user .page-tt

).

Hierarchy and Scope

Typical list markup:

<code>&lt;ul&gt;
    &lt;li&gt;
        &lt;a href="#"&gt;&lt;img src="" alt=""&gt;&lt;/a&gt;
        &lt;h3&gt;&lt;a href="#"&gt;&lt;/a&gt;&lt;/h3&gt;
        &lt;p&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ul&gt;
</code>

Two naming approaches:

<code>// Inheritance style
ul.card-list
    li.list-item
        a.item-img-link > img.item-img
        h3.item-tt > a.item-tt-link
        p.item-text

// Keyword style
ul.card-list
    li.item
        a.field-img-link > img.field-img
        h3.field-tt > a.field-tt-link
        p.field-text
</code>

Scope styles using parent classes, e.g.,

.aside-block.block--xxx > h3.block-tt .block-bd

, and apply modifiers like

.block--contact

to adjust specific sections.

Real‑World Example

For a sidebar contact list:

<code>ul.contact-list
    li
        i.item-icon.icon-font.i-xxx
        a.item-tt
        p.gray
</code>

Base styles:

<code>.gray {}
.contact-list {
    li {}
    .item-icon {}
    .item-tt {}
}
</code>

To customize only this sidebar, wrap it with a modifier class:

<code>.block--contact {
    .contact-list {
        li {}
    }
}
</code>

In summary, effective CSS class naming starts with a solid keyword set, then applies modifier conventions, hierarchical structures, and scoped rules to achieve readability, maintainability, and conflict avoidance.

Original article first published on IMWeb . Please credit the source when reposting.

frontendbest practicescssBEMclass namingstyle organization
Tencent IMWeb Frontend Team
Written by

Tencent IMWeb Frontend Team

IMWeb Frontend Community gathering frontend development enthusiasts. Follow us for refined live courses by top experts, cutting‑edge technical posts, and to sharpen your frontend skills.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.