Code Quality Help

SCSS Standards

File organisation, code style, and authoring practices that support OOCSS and maintainable stylesheets.

File structure

Adopt a layered architecture to keep structure and skin clearly separated:

Layer

Partial

Purpose

Settings

_settings.scss

Design tokens: colours, spacing, fonts, breakpoints

Tools

_tools.scss

Mixins, functions

Generic

_generic.scss

Reset, box‑sizing, basic normalisation

Objects

_objects.scss

Structural OOCSS patterns (media, grid, bare‑list, card, btn)

Skins

_skins.scss

Visual skin classes that can be applied to any object (primary, muted, danger, etc.)

Utilities

_utilities.scss

Single‑purpose helpers (.u-hidden, .u-sr-only)

All layers are imported in main.scss. Notice that skins live in their own partial – they are not attached to any specific component.

Writing style

Selectors

  • Only class selectors are used for styling; never ID, element, or attribute selectors.

  • Nesting maximum: 2 levels deep (usually only for pseudo‑classes/‑elements like &:hover). Do not nest structural sub‑parts inside their object block.

    // Bad – independent rules .media { display: flex; gap: 1rem; } .media-img { flex-shrink: 0; } .media-body { flex: 1; } // Good – nested .media { display: flex; .img { ... } // uses descendant selector }
  • For skins, write standalone rules that apply directly:

.primary { background-color: var(--color-primary); color: #fff; } .muted { color: var(--color-text-muted); }

Placeholder selectors for objects (optional)

Define structural objects as silent placeholders (%) when you want to share the base structure without emitting an unused class. Extend them in concrete classes.

.media-object { display: flex; gap: 1rem; } .media { @extend .media-object; } .grid { @extend .media-object; // example of reusing structure }

Prefer this over extending regular classes, because it keeps the compiled CSS clean and avoids unwanted grouping.

Mixins vs @extend

  • Use mixins for reusable chunks that require parameters (e.g., breakpoint helpers, responsive widths).

  • For sharing base structural styles statically, @extend on placeholders is acceptable.

  • Avoid @extend across unrelated components – it can cause selector bloat and source‑order surprises.

Variables and design tokens

  • All values come from CSS custom properties (or SCSS variables). No “magic numbers” or raw colour codes.

.card { border-radius: var(--border-radius-sm); padding: var(--spacing-md); } .primary { background-color: var(--color-primary); }
  • Skin classes like .primary only use variables; they do not set structural properties.

Media queries

Place media queries inside the selector they affect, keeping the layout and its responsive behaviour together.

.grid { display: block; @include mq(lg) { display: grid; grid-template-columns: repeat(2, 1fr); } }

Performance and output

  • Compile to a flat, single‑class selector CSS. Avoid chains like .card .card-header – use a single .card-header class instead.

  • Skins are applied as additional classes, so they add minimal extra specificity and can be combined freely.

  • Unused placeholders and skin classes can be easily removed from the output by only importing what is required, keeping the final bundle lean.

03 July 2026