CSS Tutorial 0/203 lessons ~6 min read Lesson 118

    SMACSS

    smacss smacss (scalable and modular architecture for css) by jonathan snook categorizes css into five types — base, layout, module,

    Course progress0%
    Focus
    27 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    SMACSS (Scalable and Modular Architecture for CSS) by Jonathan Snook categorizes CSS into five types — Base, Layout, Module, State, Theme — and assigns each type different specificity and naming rules. Staff engineers use SMACSS when onboarding teams to a shared stylesheet mental model: where does a new rule live, and what specificity budget does that layer get?

    SMACSS is the taxonomy that prevents "just add it to main.css" — the default failure mode of enterprise CSS.

    Business problem

    Business pressure: Without category discipline, enterprise CSS becomes a single flat file where layout hacks override module styles and theme experiments break production. SMACSS assigns each rule a category with explicit override rules — layout can affect modules, but modules should not redefine global layout.

    • Onboarding: New hires know whether a rule belongs in layout vs module within first PR review.
    • Refactor safety: State classes are few and grep-able — .is-hidden, .is-collapsed.
    • Theme swaps: Theme layer isolates brand experiments from structural CSS.

    Why this feature exists

    Platform history: Snook documented SMACSS in 2012 when responsive redesigns exposed that page-centric CSS could not scale to component-based UIs. The book predates React but maps directly to component folders today.

    • Problem solved: Ambiguous ownership of global vs local styles.
    • Rejected alternative: One stylesheet per page — duplication and cache misses.
    • Modern role: SMACSS categories map to ITCSS layers and design-system package structure.

    Browser rendering perspective

    Rendering impact: Category order in the file affects cascade resolution when specificity is equal — SMACSS recommends ordering categories so theme and state win predictably without !important.

    • Cascade layers (@layer): Modern SMACSS implementations map categories to explicit layers — base, layout, components, utilities.

    Internal browser workflow

    Workflow: Author identifies rule type → places in correct file/layer → uses category-appropriate naming → state classes prefixed with is- or has-.

    • Base: element defaults, no classes.
    • Layout: major regions — l-header, l-sidebar.
    • Module: reusable components — card, nav.
    • State: .is-active on module or layout.
    • Theme: visual skin overrides — often token-driven.

    Feature deep dive

    Five categories: each with naming and specificity guidance.

    css
    /* Base — single element */
    body { margin: 0; font-family: system-ui; }
    a { color: var(--link); }
    /* Layout — l- prefix, low specificity */
    .l-main { max-width: 72rem; margin: 0 auto; }
    /* Module — component */
    .nav { display: flex; }
    .nav__item { }
    /* State — is-/has- prefix, can combine */
    .nav__item.is-active { font-weight: 600; }
    .card.is-loading { opacity: 0.6; }
    /* Theme — override colors */
    .theme-dark .nav { background: #1e293b; }

    Syntax

    Prefixes: Layout l- (optional), state is-/has-, module unprefixed or BEM. Theme often on html or body class.

    Examples

    State on module — JS toggles is-expanded, CSS handles presentation:

    css
    .accordion__panel { display: none; }
    .accordion__panel.is-expanded { display: block; }
    .accordion__trigger[aria-expanded="true"] { border-color: var(--accent); }

    Real-world use

    Early Bootstrap grid + components followed SMACSS-like separation. Many agency style guides from 2012–2018 documented SMACSS before ITCSS gained adoption. WordPress theme frameworks use layout/module splits.

    Real production example

    Pattern: Monorepo packages — packages/css-base, css-layout, css-modules, css-themes. Import order enforced in build entry.

    • CI: stylelint plugin rejects layout rules in module files.
    • Docs: ADR maps React component folder to SMACSS category.

    Enterprise use case

    Enterprise: Carbon separates reset, grid, and component SCSS partials — SMACSS category thinking even with React components.

    • Atlassian: Theme classes on shell; modules stay theme-agnostic.

    Accessibility considerations

    A11y: State classes must mirror ARIA — is-expanded paired with aria-expanded. Do not use state classes alone for semantic state.

    • Focus: .is-focus-visible only if native :focus-visible insufficient.

    Performance considerations

    Performance: Theme selectors like .theme-dark .module add matching cost — prefer custom properties on root for theme switches.

    SEO considerations

    SEO: .is-hidden with display:none on content blocks hides from crawlers — use for chrome, not article body.

    Scalability considerations

    Scale: State class proliferation (is-loading-42) signals missing module modifiers — consolidate.

    Common production issues

    Failures: Layout classes used inside modules — .l-grid .card couples components to page grid.

    Debugging guide

    Debug: Identify category of winning rule — if module beats layout incorrectly, specificity or order violation.

    Best practices

    • Prefix state classes consistently — is- or has-.
    • Modules never define page layout width.
    • Theme via tokens on :root where possible.
    • Document category in each SCSS partial header comment.

    Anti-patterns

    • Global .active state — collides across modules.
    • Theme rules that change layout dimensions.
    • Base layer element selectors that modules cannot override cleanly.

    Trade-offs

    • Benefit: clear mental model and file organization.
    • Cost: category debates on edge-case components.
    • vs ITCSS: SMACSS is categorical; ITCSS adds explicit specificity pyramid.

    Architecture review questions

    • Where does a sticky footer rule live — layout or module?
    • How do state classes interact with ARIA in our accordion?
    • Are theme overrides token-based or selector-based?

    Interview questions

    List SMACSS categories and one rule per category.(Beginner)

    Base: <code>body { margin:0 }</code>. Layout: <code>.l-main</code>. Module: <code>.card</code>. State: <code>.is-active</code>. Theme: <code>.theme-dark</code> overrides.

    Follow-up: How does state differ from BEM modifier?

    SMACSS vs ITCSS — when use which?(Advanced)

    SMACSS categorizes rule types; ITCSS orders layers by specificity. Often combined — SMACSS categories inside ITCSS layers. ITCSS adds tools/utilities at top of cascade.

    Follow-up: Map SMACSS to @layer

    Hands-on exercise

    Exercise: Split a monolithic CSS file into SMACSS folders. Add stylelint boundaries.

    Staff engineer notes

    • State classes should be few — if you have 30 is-* classes, modules lack modifiers.

    Common pitfalls

    • Treating every modifier as global state class.

    Try it yourself

    Edit the CSS panel — the preview updates live. Use DevTools Performance and Accessibility panels to validate.

    Try it yourself

    Preview

    Summary

    SMACSS provides a five-category taxonomy for organizing CSS at scale — guiding where rules live and how they override each other without specificity wars.

    Key takeaways

    • SMACSS categorizes CSS into base, layout, module, state, theme.
    • Prefixes and specificity rules prevent global collisions.
    Ready to mark this lesson complete?Track your journey across the entire course.