Class Naming

CSS class naming convention for ui-foundations components and patterns.

Convention

ui-foundations uses flat compound classes — no BEM double-underscores, no namespace prefixes.

Structure

.component                     → root element
.component-part                → structural child (compound with hyphen)
.component-part.variant        → variant as modifier class
.component.variant             → root-level variant
.component.is-state            → state class (always .is- prefix)

Rules

  1. Root class = bare component name: .calendar, .button, .checkbox
  2. Parts use hyphen-compound: .calendar-header, .calendar-cell, .input-field
  3. Variants are additional classes: .button.ghost, .badge.brand, .divider.subtle
  4. States use .is- prefix: .is-hover, .is-selected, .is-disabled, .is-today
  5. No double-underscores (__): use hyphen-compound instead
  6. No namespace prefixes: never .ui-calendar or .uif-button
  7. No BEM modifiers (--): use multi-class instead (.button.ghost not .button--ghost)

Examples

/* ✓ Correct */
.calendar { }
.calendar-header { }
.calendar-cell { }
.calendar-cell.is-selected { }
.button.ghost { }
.input-field { }

/* ✗ Incorrect */
.calendar__header { }        /* no double-underscore */
.calendar-cell--selected { } /* no BEM modifier */
.ui-calendar { }             /* no namespace */
.button--ghost { }           /* use multi-class */

Why This Convention

  • Readability: .calendar-cell.is-selected reads as plain English
  • Flat specificity: all selectors stay at one or two class levels
  • Composable: .button.ghost.calendar-cell — stack classes freely
  • Scannable: in DevTools you see the full state without decoding
  • Aligned with tokens: tokens use hyphen-compound too (--calendar-cell-background-hover)

Migration

Some older components still use __ (e.g. .accordion-item__content, .form-field__helper). New components must use hyphen-compound. Existing components will be migrated incrementally — no breaking changes to consumers until a major version.