Skip to main content
← 🎨 CSS as a design systemΒ·Module B8 Β· Lesson 5
TaskBuild .button with custom-property props (--bg, --fg, --pad-x, --pad-y) and three variants. .button.danger overrides --bg. .button.success overrides --bg. .button.large overrides --pad-x and --pad-y.

Custom properties as a component API

100 XP8 min
Theory

Components that accept "props" via CSS vars

.button {
  --bg: #3B82F6;
  --fg: white;
  --pad-x: 20px;
  --pad-y: 10px;

  background: var(--bg);
  color: var(--fg);
  padding: var(--pad-y) var(--pad-x);
  border-radius: 8px;
  border: none;
}

/* Variants override the vars */
.button.danger { --bg: #DC2626; }
.button.success { --bg: #22C55E; }
.button.small { --pad-x: 12px; --pad-y: 6px; }
.button.large { --pad-x: 28px; --pad-y: 14px; }

The COMPONENT defines its API via internal custom properties. VARIANTS just override the props.

Why this beats classes-for-everything

Compare to the BEM way:

/* BEM β€” adds a new rule per variant */
.button { background: #3B82F6; padding: 10px 20px; }
.button--danger { background: #DC2626; }
.button--small { padding: 6px 12px; }

With BEM, the variant needs to know which CSS properties to override. With custom-property props, the component declares its API ONCE β€” variants just set the props.

Use cases

  • Spacing tokens (--gap, --padding).
  • Sizing tokens (--max-width, --min-height).
  • Visual tokens (--bg, --fg, --accent).
  • Animation timing (--duration).

The contract

  • Define vars at the component root (.button { --bg: ... }).
  • Use them in the component's CSS (background: var(--bg)).
  • Allow variants to OVERRIDE them.
  • Optionally use the fallback syntax var(--bg, fallback-default) for resilience.

This is THE modern way to build a CSS design system without preprocessors or CSS-in-JS.

πŸ”’

Sign up to start coding

Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial β€” card required, cancel anytime.

Sign up β€” free trial β†’

First 10 lessons in each track are free. No card needed for those.

← PreviousNext lesson β†’

Get one Python or web tip a day β€” by email

Short, hand-written, no spam. Unsubscribe in one click.