Polotno
Getting started

Theme

Enable dark mode and override Polotno UI styles with CSS

Styling Polotno Design Editor to match your design.

The default Polotno UI ships with its own design system. Load its styles once with import 'polotno/ui.css'. You can theme the editor in a few layers, from highest to lowest effort:

  1. Theme variables — recolor the whole UI by setting a few CSS variables (see below).
  2. Dark mode — a single class toggle (below).
  3. Canvas chrome props — recolor selection, guides, transformers, etc. via <Workspace> props (see below).
  4. CSS overrides — target Polotno's stable polotno-* selectors for finer changes.

If you build custom UI, reuse the editor's own components from polotno/primitives so they stay consistent with the theme.

Theming with CSS variables

The UI's colors, border radius, and font all come from CSS variables. Define them on :root (or any element that wraps the editor) to recolor it — you only need to set the ones you want to change; everything else keeps its default.

:root {
  /* main accent (primary buttons, active states) */
  --primary: #6d28d9;
  --primary-foreground: #ffffff;

  /* base surface and text */
  --background: #ffffff;
  --foreground: #1a1a1a;

  /* corner roundness and UI font */
  --radius: 0.5rem;
  --font-sans: 'Inter', sans-serif;
}

Values accept any CSS color (hex, rgb(), oklch(), etc.). If your app already defines a theme with these variables, the editor matches it automatically — no extra setup.

All variables

Each color also has a -foreground pair (the text/icon color drawn on top of it) where relevant.

VariableControls
--background / --foregroundBase editor surface and default text
--card / --card-foregroundRaised surfaces — panels, cards
--popover / --popover-foregroundPopovers, dropdowns, menus
--primary / --primary-foregroundMain accent — primary buttons, active states
--secondary / --secondary-foregroundSecondary buttons and controls
--muted / --muted-foregroundMuted backgrounds and secondary text
--accent / --accent-foregroundHover / selected highlight
--destructive / --destructive-foregroundDelete and other dangerous actions
--borderBorders and dividers
--inputInput field borders
--ringFocus ring
--sidebar, --sidebar-foreground, --sidebar-primary, --sidebar-accent, --sidebar-border, --sidebar-ring (and -foreground pairs)The side-panel tab rail
--chart-1--chart-5Color palette for chart elements
--radiusCorner roundness of controls and surfaces
--font-sansUI font family

To theme dark mode, set the variables under the dark class:

.dark {
  --primary: #a78bfa;
  --background: #18181b;
  --foreground: #fafafa;
}

Isolating the change to the editor

The plain variables above are shared — setting --primary on :root also affects any of your own UI that reads it. To re-theme only the editor without touching the rest of your app, set the same names with a --pn- prefix instead. They take priority over the plain variables for Polotno, and your app keeps its own values.

:root {
  --pn-primary: #6d28d9;
  --pn-background: #ffffff;
  --pn-radius: 0.5rem;
}

Every variable in the table has a --pn- counterpart (--pn-primary, --pn-border, --pn-radius, --pn-font-sans, …).

How to enable dark theme?

To enable dark mode, add the dark class to any editor container (for example, the body).

<body class="dark">
  <div id="container"></div>
</body>

Alternatively, set data-polotno-theme="dark" directly on a Polotno container — useful when you can't add a dark class to an ancestor.

<div data-polotno-theme="dark">
  <!-- editor -->
</div>

How to change styles of side panel and toolbar?

For finer changes, use CSS. Inspect the DOM to find class names. Polotno keeps a set of stable polotno-* selectors you can target (prefer these over utility classes, which can change between releases).

/* overwrite colors for side-panel tabs */
.dark .polotno-side-tabs-container .polotno-side-panel-tab:hover,
.dark .polotno-side-tabs-container .polotno-side-panel-tab.active {
  background-color: #c8c52d;
  color: white;
}

Live demo

Pick a preset to recolor the editor live, toggle light/dark, and hit Show code to copy the CSS variables (with or without the --pn- prefix).

Theming the canvas chrome

All editor canvas chrome — selection rectangles, transformer handles, snap guides, distance guides, crop overlays, loading/error indicators, rulers, and the hover highlighter — is themed via props on the <Workspace> component. Each prop is optional and merges with the default.

Example: recolor the editor accent away from the default blue.

<Workspace
  store={store}
  selectionRectStroke="#c8c52d"
  selectionRectFill="rgba(200, 197, 45, 0.3)"
  snapGuideStroke="#c8c52d"
  transformLabelFill="#c8c52d"
  highlighterStyle={{ stroke: '#c8c52d' }}
/>

See the Workspace page for the full list of canvas styling props.

The legacy setTransformerStyle, setHighlighterStyle, setInnerImageCropTransformerStyle, and setOuterImageCropTransformerStyle globals from polotno/config do the same thing globally and are deprecated — prefer the per-Workspace props.

On this page