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
Containerdisplay:flex/grid, gap, justify-*, align-*on the Block itself
Item (from parent)margin-top, flex, order, align-selfon parent’s > .child-block (also applies to > .element)
Internaltext-align, line-height, padding, size (sizeInternal)on the child Block / Element itself

Note: The table above shows the conceptual classification. The Stylelint rule only enforces placement for a subset: padding / overflow / size properties (when sizeInternal is enabled). Properties like text-align and line-height are conceptually internal but are not checked by the linter.

Decision criteria

  • Container: how to arrange children → write on Block itself
  • Item: adjust child placement, spacing, and flex/grid behavior from the parent → write on > .child-block / > .element (size is internal by default — details)
  • 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 & {
// ...
}

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);
}
}
}