DESIGN.md
This document describes the default light theme of Ant Design v6. The system follows semantic versioning: major releases (v5 → v6) signal an overhaul of the design language, while minor and patch releases keep this document stable. Refer to CHANGELOG.en-US.md for the per-release token drift inside a major.
Ant Design is the open-source design system Ant Group uses to ship enterprise software — primarily mid- and back-office consoles, dashboards, and operational tools. The system was created in 2015 to give large product teams a shared, opinionated foundation so they could ship dense, data-rich interfaces without re-deciding the basics on every screen.
Four values guide every decision in the system:
The palette is built from one primary brand seed, four semantic state seeds (success, warning, error, info), and neutral base colors for text and surfaces. Color seeds expand automatically through @ant-design/colors into gradient steps covering background tint, hover, active, and outline variants — change the seed, and the entire derived palette moves with it.
#1677FF was chosen as the primary because blue reads as trustworthy and focused without the corporate flatness of a darker navy or the playfulness of a saturated cyan. It is the default brand color for actions, links, focus rings, selected navigation, and active tabs.
Accessibility note: this file records Ant Design's default visual tokens. Some brand-color pairs, especially white text on #1677FF and primary text on pale selected backgrounds, are below WCAG AA's 4.5:1 contrast threshold for small text. For strict accessibility targets, darken colorPrimary through ConfigProvider or use component-specific token overrides rather than inventing one-off colors.
Neutral text and overlays in the runtime token system are expressed as rgba(0, 0, 0, α) rather than flat grey hex values. The reason is overlay: when text sits above a tinted card or a colored cell highlight, an opaque grey breaks the tint, while a transparent black blends naturally. The four standard alpha steps are 0.88 (primary text, exported here as #1F1F1F), 0.65 (secondary text, #595959), 0.45 (tertiary / description text), and 0.25 (placeholder / disabled, #BFBFBF). The hex values listed in this document are the equivalent composited result on a white surface, suitable for static export targets that require hex; downstream consumers that support alpha should prefer the rgba() form from @ant-design/cssinjs.
The preset colors (blue, purple, cyan, green, magenta, red, orange, yellow, volcano, geekblue, gold, lime; pink is a deprecated alias of magenta in runtime tokens) are reserved for tags, charts, and categorical visualization — never for primary UI affordances. Use functional colors (success/warning/error/info) for status, and reserve primary for the single most important action on each screen.
The base font size is 14 px, not 16. Enterprise consoles trade legibility headroom for information density — a 1440 px-wide window has to comfortably fit a sidebar, a header, a data table with eight columns, and a detail pane. At 14 px, a row of body copy reaches the eye-saccade sweet spot of ~75 characters at the column widths these layouts demand.
The font stack prioritizes the OS UI font in order: Apple's -apple-system, then BlinkMacSystemFont, then Windows' Segoe UI, then Android/ChromeOS' Roboto, then Helvetica Neue, then Arial, with Noto Sans covering Linux. Emoji fallbacks are kept short. The code font uses SFMono-Regular, Consolas, Liberation Mono, Menlo, and Courier in the same order.
Only two font weights appear in product UI: 400 (body, controls, menu items, tab labels) and 600 (fontWeightStrong — headings, table headers, and any title-grade typography). Thin (100–300), bold (700+), and italics are not used in interface chrome — they fight the calm, certain tone the system targets. Italics are acceptable only inside long-form documentation prose. Visual emphasis on selected/active states comes from color and stroke (border, underline), not weight.
All spacing snaps to a 4 px grid. The six-step spacing scale (unit, xs, sm, md, lg, xl → 4 / 4 / 8 / 16 / 24 / 32 px) covers every gap, gutter, and inset in the system. Magic numbers — padding: 11px, gap: 13px — do not appear in token-driven code; the input field's 11 px horizontal padding exists only because the design pre-dates the 4 px grid and a one-pixel migration would shift millions of existing screens.
Surfaces use a three-layer model:
bg-layout (#F5F5F5) — the page background. It surrounds and contains everything else.bg-container (#FFFFFF) — the surface for cards, panels, tables, and forms. This is where most content lives.bg-elevated (#FFFFFF, same hex as bg-container) — the surface for modals, dropdowns, popovers. Distinguished from bg-container not by color but by shadow.Never hard-code #FFF or #FAFAFA in product code. Read the token. The three-layer model is what lets a dark-mode algorithm flip the surface ladder without breaking layouts.
Ant Design is flat-first. Borders and tonal contrast carry hierarchy. Shadows appear only on surfaces that genuinely float above their context.
Shadow tokens are generated from colorShadow, so the same names adapt across light and dark themes. The core tiers are:
boxShadowTertiary) — the light raised-surface shadow: 0 1px 2px 0 rgba(0,0,0,0.05), 0 1px 6px -1px rgba(0,0,0,0.03), 0 2px 4px 0 rgba(0,0,0,0.03).boxShadow and boxShadowSecondary) — the standard floating-layer shadow: 0 6px 16px 0 rgba(0,0,0,0.08), 0 3px 6px -4px rgba(0,0,0,0.12), 0 9px 28px 8px rgba(0,0,0,0.05).boxShadowCard) — a card-specific raised shadow with tighter spread, used when cards need separation from the container.boxShadowDrawer*, boxShadowTabsOverflow*) — specialized tokens for edge-attached surfaces and scroll affordances.boxShadowPopoverArrow) — used only for the small triangular pointer on tooltip and popover arrows.Motion uses three durations and a small library of cubic-bezier easings, all exposed as tokens:
motionDurationFast — 0.1 s, for state changes (hover, focus, press).motionDurationMid — 0.2 s, for component-internal transitions (collapse, fade).motionDurationSlow — 0.3 s, for surface-level changes (modal enter, drawer slide).Easings are pre-defined: motionEaseInOut, motionEaseOut, motionEaseIn, motionEaseOutBack, motionEaseOutCirc, etc. Do not pick a transition-timing-function arbitrarily. If the design need does not match an existing easing, use motionEaseInOut and move on.
The default corner radius is 6 px. It is round enough to read as modern and friendly, but small enough that a 32-pixel-tall button still presents a clean, almost-rectangular silhouette suitable for dense forms.
By component class:
rounded.DEFAULT).rounded.lg).rounded.md).rounded.md).Full-pill (rounded.full, 9999 px) is reserved for circular avatars, badges, and dots — not for buttons or tags. Square (0 px) is reserved for tables and the inner edges of segmented controls. Mixing radii on adjacent elements is a smell: a card with 8 px corners should not contain a button with 16 px corners.
Component archetypes capture the system's most common surfaces and states. Each entry below maps to the token references in the YAML front-matter.
primary fill, white text, 32 px tall, 6 px radius. Hover lightens the fill to #4096FF; active darkens to #0958D9. Do not stack two primary buttons in one decision.#4096FF; the border tints to match.primary and adds an inset glow. Placeholder text uses on-surface-disabled.boxShadowCard elevation. Internal padding is 24 px on all sides; nested controls maintain 16 px gaps.rgba(0, 0, 0, 0.45) mask. Body padding is 20 px top/bottom × 24 px left/right.#E6F4FF background, primary text. This is the single visual cue for "you are here" in navigation.primary text and a 2 px primary underline. Inactive tabs are on-surface-variant. No background fill on tabs at any state.surface-container background, title-md typography (14 px / 600). Body rows alternate on hover only, not by default — the system trusts users to read dense data without zebra striping.error fill, but the dot is not a substitute for text in accessibility-critical flows.rgba(0,0,0,0.85) background, white text. Always positioned by the framework, never manually pinned.surface-container fill on hover, no text-color change. The hover affordance is enough.primary-colored buttons on the same surface. Pick one. Demote the rest to default.colors.surface, colors.surface-container, and colors.surface-layout. They reflect the three-layer model.#FFFFFF or #FAFAFA. The hex is incidental; the role is what matters.motionDurationMid (0.2 s) for any component-level transition you cannot find a more specific token for.cubic-bezier curves. Use the named easings.blue through lime) for tags, charts, and categorical visualization.Every value in the YAML front-matter above is a default produced by defaultAlgorithm — the light theme. Ant Design theming is broader than Design Token replacement: it includes algorithmic derivation, component-scoped overrides, dynamic switching, nested theme scopes, CSS variable output, static token consumption, and zero-runtime CSS extraction. See Customize Theme for the complete runtime API and examples.
The primary theme configuration entry is ConfigProvider's theme prop:
Seed token overrides. Pass theme.token to ConfigProvider to replace any seed. The primary and semantic color seeds (colorPrimary, colorSuccess, colorWarning, colorError, colorInfo) expand into derived gradients, while colorBgBase and colorTextBase drive neutral surfaces and text. Spacing, radius, and font-size seeds work the same way.
Algorithm switching. Set theme.algorithm to swap the derivation logic. defaultAlgorithm, darkAlgorithm, and compactAlgorithm can be used alone or composed as an array — do not invert colors manually; the algorithms account for non-linear palette, surface, shadow, and size relationships.
Component-level overrides. theme.components.Button (or any component's token namespace) can override a single component's Component Token and consumed Alias Token without affecting others. In component config, algorithm can opt that component into token derivation when the override should still follow seed-token relationships.
Runtime scope. Themes can switch dynamically by changing ConfigProvider.theme, and nested ConfigProvider instances create local themes that inherit unchanged tokens from their parent. Static APIs such as message.xxx, Modal.xxx, and notification.xxx do not automatically receive the surrounding context; use hook-based APIs, App, or explicit context holders when themed static feedback is required.
Token consumption and output. Use theme.useToken() inside React and theme.getDesignToken() outside React to consume resolved tokens. Use theme.cssVar when CSS variables are needed, and theme.zeroRuntime with prebuilt or extracted CSS when runtime style generation must be disabled.
For custom theme generation, keep Ant Design's interaction structure, density, state feedback, and component semantics first. Then change the smallest necessary seed set: usually colorPrimary, status colors, borderRadius, fontFamily, fontSize, and neutral surface bases. Brand pages may look distinct, but forms, tables, navigation, overlays, focus states, and validation feedback should still feel like Ant Design. Avoid generating custom CSS rules that bypass tokens, algorithms, theme.components, CSS variables, or extracted static styles; if a theme cannot be expressed through those official layers, treat that as a design-system extension rather than a one-off page style.