Skip to Content

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 setComponents affected
brand.primary['600'] alonePrimaryButton, selected Menu.Item (text + background)
focus.primaryFocus 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.surfaceSelected 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 .