Skip to content

SCSS Sections

Each Block’s SCSS file arranges sections in this order:

  1. Base structure: Block layout + Variant
  2. --shared: shared classes scoped to this Block (only when needed)
  3. --interaction: state changes and interactions (only when needed)

Example structure

.sample-block {
// Base structure ------------------------------
display: block;
&[data-variant="primary"] { ... }
> .sample-header {
// layout for child Block/Element
}
> .sample-body {
// layout for child Block/Element
}
// --shared ------------------------------------
.btn {
// shared style used only under this Block
}
// --interaction -------------------------------
@at-root & {
&:hover { ... }
&[data-state="active"] { ... }
&[aria-expanded="true"] { ... }
}
}

Base structure section

A concrete application of the one-sentence principle. Detailed rules are validated by Stylelint.

Property placement

CategoryTypical propertiesWhere to write
Container-sidedisplay:flex/grid, gap, justify-*, align-*on the Block itself
Item-side (from parent)margin-top, flex, order, align-selfon parent’s > .child
Internaltext-align, line-height, paddingon the child itself

Decision criteria

  • Container-side: how to arrange children → write on Block itself
  • Item-side: change child due to parent’s needs → write on > .child
  • Child gets complex: child arranges its own children → extract as new Block

—shared section

Collect shared classes reused only within the Block’s tree.

// --shared ----------------------------------------

Writing rules:

  • May target any descendant (not limited to >)
  • Place directly under the root Block

—interaction section

Collect styles for state changes and interactions.

// --interaction -----------------------------------
@at-root & {
// ...
}

@at-root & is used for consistency with Stylelint rules.
See the interaction-scope rule for details.

Target:

  • data-state / aria-* states
  • :hover, :focus-visible, :active
  • animation/transition declarations

Writing rules:

  • Place directly under the root Block
  • Nest pseudo-classes under the target selector

Example:

.button-container {
display: inline-block;
padding: 10px 20px;
background: #fff;
// --interaction -----------------------------------
@at-root & {
opacity: 0;
transform: translateY(10px);
transition: opacity 0.3s ease, transform 0.3s ease;
> .icon {
&:hover {
opacity: 0.8;
}
}
&[data-state="visible"] {
opacity: 1;
transform: translateY(0);
}
&:hover {
transform: translateY(-2px);
}
}
}