Skip to content

CSS Layers

Split project-wide CSS into the following three layers.

LayerRole
GlobalSite-wide values, functions, mixins, utilities
PagePer-page entry CSS (component placement)
ComponentComponent design with Block/Element + Variant/State

Global Layer

Responsible for site-wide settings, functions, mixins, resets, and utilities.

File structure by role

CategoryFilesRole
Settingsvariables.scss, global/config.scssColors, typography, spacing, breakpoints
Functions/Mixinsglobal/function.scss, global/mixin.scssNumeric conversions, media query generation, etc.
Base stylesreset.scss, base.scss, print.scssResets, element styles, print styles
Utilitiesutilities.scssSingle-purpose classes like .u-hidden, .u-sr-only
Shared animationskeyframes.scss@keyframes used across multiple components (kf- prefix)

Utility classes

Sparingly define single-purpose classes that don’t depend on structure or skin.

  • u- prefix required (e.g. .u-hidden, .u-sr-only)
  • Separate category from Block/Element (not subject to two-word/one-word rules)
  • Keep to the minimum reused site-wide

Shared animations

Centralize @keyframes used across multiple components in keyframes.scss.

  • Use a prefix like kf-
  • Place at root level only (not inside @media / @layer)

Page Layer

Per-page entry SCSS (e.g. home.scss, about.scss).

Role

  • Import components (@use)
  • Place child Blocks inside the page root class (e.g. .main-container)
  • Page-specific spacing, backgrounds, etc.

Scope

DoesDoes not
Import and place componentsDefine component internals
Adjust spacing between BlocksDefine Block internal layout

Example

@use "@styles/partials/global" as *;
@use "@components/hero/hero-container";
.main-container {
> .hero-container {
// @components/hero/hero-container.scss
margin-top: 0;
}
}

Component Layer

Consistent rules for Block/Element structure, Variant/State separation, SCSS sections, and file management.

  • Block (two words): the component itself (e.g. .hero-container)
  • Element (one word): an element within a Block (e.g. .title)
  • Variant / State: data attributes (default) or class mode
  • One Block per file: each Block maps to one SCSS file
  • @keyframes: component-specific ones go at root level, end of file

See Components for details.

Directory structure example

src/
├── styles/ # Global layer
│ └── partials/
│ ├── global/
│ │ ├── config.scss
│ │ ├── function.scss
│ │ ├── index.scss
│ │ └── mixin.scss
│ ├── base.scss
│ ├── keyframes.scss
│ ├── print.scss
│ ├── reset.scss
│ ├── utilities.scss
│ └── variables.scss
├── components/ # Component layer
│ ├── common/ # Site-wide shared
│ │ └── site-header/
│ │ └── site-header.scss
│ ├── parts/ # Multi-page shared
│ │ └── hero-banner/
│ │ └── hero-banner.scss
│ └── pages/ # Page-specific
│ ├── home/
│ │ └── home-hero/
│ │ └── home-hero.scss
│ └── about/
│ └── about-intro/
│ └── about-intro.scss
└── assets/
└── css/ # Page layer
├── home.scss
└── about.scss

Sample repository (simplified)

spiracss-scss-structure