codingstairs
NotesEDULifeContact
⌕Search⌘K
koen

Navigation

  • Intro
  • Blog
  • Life

Get in touch

Send without signing in. Add your email if you'd like a reply.

  • Leave a message anonymously →
  • ✉ warragon112@gmail.com
  • KakaoTalk Open Chat ↗

© 2026 codingstairs

  • Notes
  • EDU
  • Search
  • Life
  • Contact
  • Legal
  • RSS
  • GitHub
Notes›frontend

Material Design 3 and Design Tokens

Published 2026-04-28· Updated 2026-05-18·0 views

Material Design 3 and Design Tokens

Material Design is a design system Google announced in 2014. It went through a major revision in 2021 with Material 3 (M3).

1. The history of Material Design

Version Announced Event
Material 1 2014 (Google I/O) Announced by Matías Duarte. Paper and ink metaphor.
Material 2 2018 Component standardization. Material Theming.
Material 3 2021 "Material You". Dynamic color (HCT color space).

The major changes of Material 3 are summarized in two points.

① Dynamic color — automatically generates the entire color palette from a user wallpaper (Android 12+) or a single source color
② Design tokens as a first-class model — components no longer hard-code their attributes; they reference tokens instead

2. Design tokens

The W3C Design Tokens Community Group (DTCG) has been working on standardization since 2021. A token is a small named value of a design decision.

{
  "color": {
    "primary": { "$value": "#6750A4", "$type": "color" }
  },
  "spacing": {
    "sm": { "$value": "8px",  "$type": "dimension" },
    "md": { "$value": "16px", "$type": "dimension" }
  }
}

Tools like Style Dictionary (Amazon) translate this JSON into CSS variables, Swift, and Kotlin.

3. M3 token categories

Category Example tokens
Color md.sys.color.primary, md.sys.color.on-primary, md.sys.color.surface
Typography md.sys.typescale.headline-large, md.sys.typescale.body-medium
Shape md.sys.shape.corner.small, md.sys.shape.corner.large
Elevation md.sys.elevation.level0~`level5`
Motion md.sys.motion.duration.short2, md.sys.motion.easing.standard
State layer opacity for hover/focus/pressed/dragged

Tokens are layered into three tiers.

  • ref (reference) — atomic value. md.ref.palette.primary40 = #6750A4.
  • sys (system) — token with semantic meaning. md.sys.color.primary = ref.palette.primary40.
  • comp (component) — per component. md.comp.button.filled.container.color = sys.color.primary.

Thanks to this layering, dark mode, dynamic color, and brand variants only need to swap the sys layer; components follow.

4. HCT color space

M3's dynamic color uses the HCT (Hue, Chroma, Tone) color space. Created by Google by combining CAM16 + L*, it is advantageous for accessibility (contrast ratio) calculations because perceived lightness becomes close when comparing within the same Tone.

The material-color-utilities (Google) library provides:

  • Generate five tonal palettes (primary, secondary, tertiary, neutral, neutral-variant) from a single source color.
  • 13 tone steps (0, 10, 20, ..., 100) per palette.
  • Automatic mapping to light/dark schemes.
import { themeFromSourceColor, hexFromArgb } from "@material/material-color-utilities"

const theme = themeFromSourceColor(0xff6750a4)
const primary = hexFromArgb(theme.schemes.light.primary)

5. Motion tokens

M3 also tokenizes motion.

  • Duration — short1short4 (50200ms), medium1medium4 (250400ms), long1long4 (450600ms), extra-long.
  • Easing — standard, emphasized, emphasized-decelerate, emphasized-accelerate.

emphasized is defined as a curve that starts fast and ends gently (around cubic-bezier(0.2, 0.0, 0.0, 1.0)).

6. Paths to implement M3 in React

Approach Library Notes
Component library MUI (Material UI) v5/v6 M2-based. v6 gradually adopting M3 tokens. Largest user base.
Web components @material/web M3 web components built by Google. Use as <md-filled-button> from React.
Tokens only material-color-utilities + custom components Combine with shadcn/Radix/Tailwind.
Tailwind integration plugins like tailwindcss-material-colors Combine utilities with tokens.

@material/web is reportedly in maintenance mode after v1.0 (2024) with no new feature development. As sustainable paths, two branches are often discussed: bringing in only the tokens and mapping them onto custom components, or following MUI's M3 support.

7. Other design systems

System Origin Notes
Material 3 Google Standard for Android/web.
Apple HIG Apple iOS/macOS guidelines.
Microsoft Fluent 2 Microsoft Windows, Office. Fluent UI React.
Carbon Design System IBM Enterprise.
Atlassian Design System Atlassian
Polaris Shopify
Ant Design Alibaba (2015) Strong in Chinese enterprise.

8. Headless + token model

A pattern frequently seen in the React ecosystem now:

  • Radix UI (accessible headless components) + Tailwind (styles) + CSS variable tokens.
  • Components are written in-house (or copied via shadcn).
  • Tokens map M3-extracted colors to CSS variables.

A strength of this model is that it borrows tokens without locking into a design system.

9. Mapping M3 tokens to CSS variables

:root {
  --md-primary:        oklch(0.50 0.13 290);
  --md-on-primary:     oklch(1.00 0    0);
  --md-surface:        oklch(0.99 0.005 90);
  --md-on-surface:     oklch(0.15 0.01 90);
  --md-outline:        oklch(0.65 0.02 90);

  --md-shape-sm: 4px;
  --md-shape-md: 12px;
  --md-shape-lg: 16px;

  --md-easing-standard: cubic-bezier(0.2, 0, 0, 1);
  --md-duration-short2: 100ms;
}

.dark {
  --md-primary:    oklch(0.78 0.13 290);
  --md-on-primary: oklch(0.20 0.05 290);
  --md-surface:    oklch(0.18 0.01 90);
  --md-on-surface: oklch(0.95 0.005 90);
}

10. Generating dynamic colors

import { argbFromHex, themeFromSourceColor, hexFromArgb }
  from "@material/material-color-utilities"

const source = argbFromHex("#0061a4")
const theme = themeFromSourceColor(source)

const tokens = {
  primary:   hexFromArgb(theme.schemes.light.primary),
  onPrimary: hexFromArgb(theme.schemes.light.onPrimary),
  surface:   hexFromArgb(theme.schemes.light.surface),
}

11. Common pitfalls

Mixing M2 and M3 — MUI tokens differ across minor versions. When M2 components and M3 components mix in one codebase, design consistency breaks.

Verifying contrast in dynamic color — HCT keeps tones aligned, but not every combination guarantees WCAG 4.5:1. Verify text/background pairs separately.

Token name churn — token names changed several times during M3 stabilization. Map to the official current names.

@material/web React integration — being a web component, it feels slightly off with React props/events. Wrappers like @lit-labs/react were often used.

Dark mode auto mapping — Material's light and dark tones are not a simple invert. Build a ref-palette and keep a separate sys mapping table.

Closing thoughts

Bringing in Material Design 3 wholesale makes the codebase heavy. Bringing in only the tokens and layering them onto custom components + Tailwind is a lighter path that still keeps consistency. Apply dynamic color in places where user freedom is high, and start ordinary apps with static tokens.

Next

  • forms-zod
  • bundlers

We refer to Material 3, Material Components GitHub, @material/web, material-color-utilities, W3C Design Tokens, Style Dictionary, MUI, and Radix UI.

More in frontend

All in this category →
  • Dashboard widget uniformity — don''t leave 4 domains with 3 widgets
  • Admin UI — ResourceTable SSOT pattern
  • Page Loading UX
  • Native Integrations — OS Features
  • OCR · STT · TTS
  • SQLite — A Single-File DB for Local Apps