Guides

Theming

GHDS is built to be re-skinned. Every color a component paints resolves through a live comp → sys → ref chain of CSS custom properties, so overriding one semantic variable re-themes everything that uses it — without touching component code or forking the library.

How theming works

@ghds/tokens emits its CSS variables as a reference chain, not as flat literals. A component reads its own --comp-* variable, which aliases a semantic --sys-* variable, which in turn aliases a raw --ref-* value:

--ref-palette-brand-600: #3e47c9;                            /* raw value      */
--sys-color-bg-primary-default: var(--ref-palette-brand-600); /* semantic role */
--comp-button-bg-primary-default: var(--sys-color-bg-primary-default); /* component */

Because the aliases stay live at runtime, redefining any link in the chain cascades downward. Override --sys-color-bg-primary-default and every component that maps to the primary role — buttons, badges, links, focus rings — updates at once.

Customizing in three steps

1. Load the token stylesheet

Import it once, at your app's entry point. This defines every default variable:

import '@ghds/tokens/css';

2. Override the variables you want

In your own global stylesheet, redefine the semantic variables under :root. You never edit component code — you re-point the tokens they already consume:

:root {
  --sys-color-bg-primary-default: #0969da;
  --sys-color-bg-primary-hover:   #0757ba;
  --sys-color-text-link:          #0969da;
  --sys-color-border-focus:       #218bff;
}

3. Cover dark mode

GHDS switches themes with a data-theme="dark" attribute (falling back to prefers-color-scheme). The dark theme re-declares the semantic variables, so set your dark values at the same specificity or they'll be overridden:

[data-theme="dark"] {
  --sys-color-bg-primary-default: #218bff;
  --sys-color-text-link:          #6cb6ff;
}

Which layer should I override?

The full list of semantic variables and their default light/dark values lives on the Design Style page.

Playground

Adjust the semantic colors and watch real GHDS components re-theme. Switch between Light and Dark to set each theme's values independently — the generated CSS emits a :root block and a [data-theme="dark"] block, ready to paste into your stylesheet.