TaskBuild a BEM-named card and a @scope-equivalent. .card__title vs @scope (.card-modern) { h2 { ... } }. Show the same visual result with both naming conventions.
BEM and the post-BEM era
75 XP6 min
Theory
BEM (Block Element Modifier) β the 2014 naming convention
<div class="card card--featured"> <h2 class="card__title">Title</h2> <p class="card__description">Description</p> <button class="card__action card__action--primary">Click</button> </div>
blockβ.cardblock__elementβ.card__title(a child of card)block--modifierβ.card--featured(variant of card)block__element--modifierβ.card__action--primary
The naming convention guarantees no accidental cascade conflicts. The trade-off: VERY verbose HTML and CSS.
When BEM made sense
Pre-2020: no @scope, no @layer, no custom-property prop pattern. BEM's verbose names were the SAFEST way to avoid cascade fights in a 50-developer codebase.
When BEM is overkill in 2026
For greenfield projects with @scope + @layer + custom properties, you DON'T need BEM's full verbosity:
<div class="card featured"> <h2>Title</h2> <p>Description</p> <button class="action primary">Click</button> </div>
@scope (.card) {
h2 { ... }
p { ... }
.action { ... }
.action.primary { ... }
}
.card.featured { ... }Same isolation guarantees, half the typing.
Three valid modern patterns
- Tailwind/utility-first β short component names + utility classes in HTML.
- @scope + nested β short class names, scoping handled by @scope.
- BEM β still valid for huge teams or legacy migration paths.
Pick one per project. Don't mix.
π
Sign up to start coding
Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial β card required, cancel anytime.
Sign up β free trial βFirst 10 lessons in each track are free. No card needed for those.