Theming
Canvas Kit v16 components are Sana-aligned out of the box. The Sana Canvas theme is a separate, opt-in step that updates brand colors, neutrals, surfaces, and shapes at the application level.
For a full list of what changes when you opt in, see the v16 Upgrade Guide .
Sana Canvas Theme
Import the Sana variables last in your root CSS and set data-theme="sana-canvas" on <html>.
/* index.css — order matters */
@import '@workday/canvas-tokens-web/css/base/_variables.css';
@import '@workday/canvas-tokens-web/css/brand/_variables.css';
@import '@workday/canvas-tokens-web/css/component/_variables.css';
@import '@workday/canvas-tokens-web/css/system/_variables.css';
@import '@workday/canvas-tokens-web/css/sana/_variables.css';
:root {
/* Optional — override only if you have a custom brand color */
--cnvs-brand-primary-600: var(--cnvs-base-palette-magenta-600);
}<html lang="en" data-theme="sana-canvas"></html>Classic Canvas (without Sana theme)
If you are not opting into the Sana Canvas theme, omit data-theme from <html>. The :root
tokens apply as-is — no theme prop on CanvasProvider is required.
<html lang="en"></html>import {CanvasProvider} from '@workday/canvas-kit-react/common';
<CanvasProvider>
<App />
</CanvasProvider>The sana stylesheet only defines [data-theme="sana-canvas"] overrides. Without that attribute,
those rules do not apply.
If your application has opted into Sana globally but one subsection needs classic Canvas branding,
use defaultBranding on a scoped CanvasProvider:
import {CanvasProvider, defaultBranding} from '@workday/canvas-kit-react/common';
<CanvasProvider className={defaultBranding}>
<ClassicCanvasSection />
</CanvasProvider>Scoped Theming
Most application teams should use the Sana Canvas theme globally and not pass a theme prop to
CanvasProvider. Use scoped theming only when a section of your app needs a different brand — for
example, embedding Canvas in a third-party application, multi-tenant branding, or popup parity.
The theme prop accepts a numerical brand object. Each key maps 1:1 to a --cnvs-brand-* CSS
variable.
| You set | Components affected |
|---|---|
brand.primary['600'] alone | PrimaryButton, selected Menu.Item (text + background) |
focus.primary | Focus rings, border primary (independent of primary brand) |
brand.action.* | PrimaryButton (read before brand.primary) |
brand.critical.* | TextInput error, critical accents |
brand.caution.* | TextInput caution, caution focus |
brand.positive.* | Checkbox, Radio checked states |
brand.neutral.* | Neutral brand text/surfaces |
selected.fg / selected.surface | Selected list/menu states directly |
Focus does not follow primary. Setting only brand.primary['600'] leaves focus rings at the
default blue unless you also set focus.primary.
import {CanvasProvider} from '@workday/canvas-kit-react/common';
import { base } from '@workday/canvas-tokens-web';
<CanvasProvider theme={{brand: {primary: {'600': base.magenta600}}}}>
<ScopedSection />
</CanvasProvider>Popups (including menus, selects, modals, and toasts) portal to document.body — outside the
parent component’s DOM hierarchy. How theming reaches them:
Preferred — you control the document root: set data-theme="sana-canvas" on the <html>
element. Popups inherit Sana CSS variables automatically; no theme prop needed:
import {CanvasProvider} from '@workday/canvas-kit-react/common';
// <html data-theme="sana-canvas">
<CanvasProvider>
<App />
</CanvasProvider>Scoped / no document-root control: if you cannot set data-theme on <html> (embedded apps,
microfrontends, third-party shells), pass both data-theme="sana-canvas" and
sanaCanvasProviderTheme to CanvasProvider. The preset supplies Sana’s brand variables, and
Canvas Kit forwards the data-theme attribute onto the popup stack container — so portaled
menus, modals, and dialogs match the same [data-theme="sana-canvas"] selector and pick up the
rest of the theme (shape, depth, type, non-brand system colors) through normal cascade:
import {CanvasProvider, sanaCanvasProviderTheme} from '@workday/canvas-kit-react/common';
<CanvasProvider theme={sanaCanvasProviderTheme} data-theme="sana-canvas">
<App />
</CanvasProvider>sanaCanvasProviderTheme is also useful in tests without global Sana CSS or with custom popup
hosts outside the normal document flow.
See the Sana Canvas Storybook story for a side-by-side comparison of global and scoped branding.
View token documentation here .