Skip to main content
Version: 3.0.0-beta

Migrating to 3.0.0-beta colours

Two generations of EDS colour are in use, and each needs a different route. This page starts with the one thing that decides how you approach either of them.

No value carries over

Not one of the 115 semantic colours in 2.0.0-beta resolves to the same value as any 3.0.0-beta token, and the 1.x palette was replaced outright. The scale is now contrast-driven rather than lightness-driven, so matching your old colours by eye, or by nearest hex, gives you a palette that fails contrast in one scheme or the other.

Map by role: what was this colouring, and what was it doing. The pairs below are matched that way, and the swatches show how large a change to expect.

Coming from EDS 1.x​

1.x named colours by component role in a flat set of hand-picked hex values: colors.interactive.primary__resting, colors.text.static_icons__default. There were 75 tokens in five groups, and states were suffixes: __resting, __hover, __selected, __activated.

3.0.0-beta names colours by surface, behaviour, tone, level and state. That is five questions where 1.x asked one, which is why a single old token often has more than one right answer. Getting Started explains how to read a name, and it is worth reading before you start rather than after.

Text​

static_icons__* covered both text and icons. 3.0.0-beta separates them, because a thin icon stroke needs more contrast than a letterform of the same size. Everything below has an icon.* twin.

EDS 1.x3.0.0-beta
text.static_icons__defaulttext.primary
text.static_icons__secondarytext.secondary
text.static_icons__tertiarytext.tertiary
text.static_icons__primary_whitetext.invertedOn a solid accent fill use text.on-emphasis.accent instead.

Backgrounds and surfaces​

The ui group was a small set of planes plus three status tints. The planes map cleanly. The status tints become non-interactive tone fills, which is the group for anything that carries meaning but cannot be clicked.

EDS 1.x3.0.0-beta
ui.background__defaultbackground.surface
ui.background__lightbackground.canvas
ui.background__mediumno equivalentUsed for both fills and dividers. Pick background.non-interactive.neutral.muted or border.non-interactive.neutral.default by role.
ui.background__scrimoverlay.scrim
ui.background__overlayoverlay.scrim
ui.background__semitransparentno equivalentColour tokens are opaque now, so translucency has no token.
ui.background__infobackground.non-interactive.info.muted
ui.background__warningbackground.non-interactive.warning.muted
ui.background__dangerbackground.non-interactive.danger.muted

Interactive colours​

The largest group, and the one that changes shape most. Three things to know before reading it:

  • primary and secondary are not tones. They described a component's rank. 3.0.0-beta uses accent for the primary action and neutral for the secondary one, and rank is expressed by choosing emphasis or muted.
  • __resting is now default, and __activated is now pressed. active was read as "currently on" about as often as "being pressed".
  • __highlight was doing two different jobs, a muted tint and a selection state. Those are now muted and selected, and only accent and neutral have selected.
EDS 1.x3.0.0-beta
interactive.primary__restingbackground.interactive.accent.emphasis.default
interactive.primary__hoverbackground.interactive.accent.emphasis.hover
interactive.primary__hover_altbackground.interactive.accent.muted.hover
interactive.primary__selected_highlightbackground.interactive.accent.selected.default
interactive.primary__selected_hoverbackground.interactive.accent.selected.hover
interactive.secondary__restingbackground.interactive.neutral.emphasis.default
interactive.secondary__highlightbackground.interactive.neutral.muted.default
interactive.secondary__link_hovertext.interactive.link.hover
interactive.danger__restingbackground.interactive.danger.emphasis.default
interactive.danger__hoverbackground.interactive.danger.emphasis.hover
interactive.danger__highlightbackground.interactive.danger.muted.default
interactive.danger__texttext.on-muted.danger
interactive.warning__restingbackground.interactive.warning.emphasis.default
interactive.warning__hoverbackground.interactive.warning.emphasis.hover
interactive.warning__highlightbackground.interactive.warning.muted.default
interactive.warning__texttext.on-muted.warning
interactive.success__restingbackground.interactive.success.emphasis.default
interactive.success__hoverbackground.interactive.success.emphasis.hover
interactive.success__highlightbackground.interactive.success.muted.default
interactive.success__texttext.on-muted.success
interactive.disabled__fillbackground.interactive.disabled
interactive.disabled__borderborder.interactive.disabled
interactive.disabled__texttext.interactive.disabled
interactive.focusborder.interactive.focus
interactive.link_on_interactive_colorstext.on-emphasis.accent
interactive.icon_on_interactive_colorsicon.on-emphasis.accent
interactive.text_highlightbackground.interactive.accent.selected.defaultSelection is a state, so it now sits under selected rather than under a tone tint.
interactive.link_in_snackbarsno equivalentThere is no token for this. A link on background.inverted takes text.inverted, so raise a request if you need a distinct value.
interactive.pressed_overlay_darkno equivalentStates are named colours now, so there is no overlay. Use the pressed value of the token you started from.
interactive.pressed_overlay_lightno equivalentSame as the dark overlay above.

Table colours​

1.x shipped table fills as their own tokens. 3.0.0-beta has no component-specific colour: a table cell is a surface, and a hovered row is an interactive neutral fill. Use the same tokens you would use anywhere else.

EDS 1.x3.0.0-beta
interactive.table__cell__fill_restingbackground.surface
interactive.table__cell__fill_hoverbackground.interactive.neutral.muted.hover
interactive.table__cell__fill_activatedbackground.interactive.neutral.selected.default
interactive.table__header__fill_restingbackground.canvas
interactive.table__header__fill_hoverbackground.interactive.neutral.muted.hover
interactive.table__header__fill_activatedbackground.interactive.neutral.selected.default

infographic (24 tokens) becomes data-visualization.*, but this is a re-palette rather than a rename. 3.0.0-beta has ten categorical hues of five steps each, plus a sequential and a diverging ramp, and none of them corresponds to an old substitute__* or primary__* value. Re-pick your series colours from the palette.

logo (2 tokens) has no equivalent. Brand marks are not part of the colour scale.

Coming from 2.0.0-beta​

This route is closer to a translation. emphasis and muted already exist, tones already exist, and fill, border and text are already separated. Four things change.

Dynamic colour is removed​

The Appearance collection and appearance-switching at the semantic-colour level are gone. There is one approach now: semantic colour, where the tone is part of the token name.

If you relied on a generic role token resolving to a different tone depending on context, name the tone explicitly. If you have data-color-appearance in your markup, or appearance modes in your Figma file, those come out.

Names are reordered, and fill is dropped​

2.0.0-beta put the tone before the surface word and used fill. 3.0.0-beta puts the surface first, drops fill, and adds the interactive split:

bg.accent.fill.emphasis.hover 2.0.0-beta
background.interactive.accent.emphasis.hover 3.0.0-beta

The interactive split is new​

This is the part that needs a decision rather than a rename. In 2.0.0-beta, a tinted banner and a tinted button could share --eds-color-bg-accent-fill-muted-default. They cannot now: the button is background.interactive.* and carries hover and pressed values, the banner is background.non-interactive.* and has none.

So when you meet a fill token, ask whether the thing it colours responds to input. Usage covers the distinction.

active becomes pressed​

Interactive active tokens become pressed states, not selected levels. Selection has its own background level on accent and neutral, with default, hover and pressed states.

Surfaces and planes​

2.0.0-beta3.0.0-beta
bg.canvasbackground.canvas
bg.surfacebackground.surface
bg.floatingbackground.floating
bg.inputbackground.input
bg.backdropno equivalentUnder review together with overlay.scrim; the two describe the same job.
bg.disabledbackground.interactive.disabled

Fills​

The pattern below repeats for all six tones. accent is shown; substitute neutral, info, success, warning or danger for the rest.

2.0.0-beta3.0.0-beta
bg.accent.fill.emphasis.defaultbackground.interactive.accent.emphasis.default
bg.accent.fill.emphasis.hoverbackground.interactive.accent.emphasis.hover
bg.accent.fill.emphasis.activebackground.interactive.accent.emphasis.pressedactive became pressed.
bg.accent.fill.muted.defaultbackground.interactive.accent.muted.default
bg.accent.canvasbackground.non-interactive.accent.mutedA tinted plane that cannot be clicked is non-interactive now.
bg.accent.surfacebackground.non-interactive.accent.default

Borders​

The rows below map old border roles to non-interactive borders: subtle / medium / strong becomes muted / default / emphasis. For a border that responds to input, decide its role instead of translating by strength alone. Interactive borders have only muted and emphasis levels, each with default, hover and pressed states.

2.0.0-beta3.0.0-beta
border.accent.subtleborder.non-interactive.accent.muted
border.accent.mediumborder.non-interactive.accent.default
border.accent.strongborder.non-interactive.accent.emphasis
border.subtleborder.non-interactive.neutral.muted
border.focusborder.interactive.focus
border.disabledborder.interactive.disabled

Text​

Tone-coloured text is now named for what it sits on rather than for how strong it is. This makes the pairing checkable: text.on-muted.accent is the foreground for an accent muted fill. Check the actual fill, foreground, states, schemes and typography with APCA before shipping.

2.0.0-beta3.0.0-beta
text.strongtext.primary
text.subtletext.secondary
text.accent.strongtext.on-muted.accentTone-coloured text sits on a tinted fill, so it is named for what it sits on.
text.accent.strong.on-emphasistext.on-emphasis.accent
text.accent.subtle.on-emphasisno equivalentOnly one foreground per tone on an emphasis fill now. Use text.on-emphasis.accent.
text.linktext.interactive.link.default
text.disabledtext.interactive.disabled

Checking your work​

Use APCA to assess text and controls against their actual backgrounds in both schemes and all applicable states, with the intended text size and weight. Do not treat a default-state pairing as proof that its hover and pressed states also pass. See Contrast and Foreground pairing.