SCSS Sections
Each Block’s SCSS file arranges sections in this order:
- Base structure: Block layout + Variant
--shared: shared classes scoped to this Block (only when needed)--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
| Category | Typical properties | Where to write |
|---|---|---|
| Container-side | display:flex/grid, gap, justify-*, align-* | on the Block itself |
| Item-side (from parent) | margin-top, flex, order, align-self | on parent’s > .child |
| Internal | text-align, line-height, padding | on 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); } }}