--dkl-* CSS styling tokens (CSS custom properties),
each with a built-in fallback. There are two layers:
- Global brand tokens (
--dkl-color-*,--dkl-radius,--dkl-font-family) — shared by every component, so setting one re-themes all of them at once. - Per-component tokens (
--dkl-price-*,--dkl-vp-*,--dkl-badge-*,--dkl-og-*) — fine control over a single component; documented on each component’s Styling & data page.
:root rule in your theme stylesheet, an
inline style on the tag, or the scoped rule an app block emits.
Global brand tokens
The embed emits these on:root. They back every component, and each component’s own
--dkl-<widget>-* tokens take precedence over them for fine-grained control.
Component font family. Custom font families must be installed on the theme.
--dkl-color-text
Default text colour.
--dkl-color-accent
Accent / selected state.
--dkl-color-success
Success / savings colour.
--dkl-color-border
Border colour.
--dkl-radius
Corner radius for all components.
Per-component style tokens
Each component adds its own tokens (and, where relevant, CSS parts and light-DOM classes) on top of the global ones. See its Styling & data page for the full list:Discount Price
--dkl-price-* tokens and ::part() targets.Volume Picker
--dkl-vp-* tokens, CSS parts, and light-DOM classes.Discount Badge
--dkl-badge-* tokens (light-DOM, host-only).Order Goal
--dkl-og-* tokens and light-DOM classes.App block vs. web component
Inside an app block, the editor’s styling settings are written into a scoped
<style>
rule the block emits — so merchants style it entirely from the theme editor. A **web component
** has no block context, so you style it by setting the same --dkl-* tokens in your own
CSS. Every token has the same default in both places, so a web component with no
overrides looks identical to a default app block.Targeting structural elements
Tokens cover colours, sizes, and spacing. For anything structural, components expose two mechanisms depending on where the element lives:- Shadow-DOM elements are reached with
::part(name)from any rule — parts pierce the shadow boundary. You can add states (::part(price):hover) but cannot descend into a part (::part(price) spandoes not work). - Light-DOM elements are reached with their class, like any other markup. They’re already styled by the component’s stylesheet, so override by matching the class and winning on specificity (or, preferably, use a token where one exists).
Money formatting. The price and volume picker reformat prices in JavaScript as tiers and
variants change. To stay byte-identical to your server-rendered Liquid
money filter, each
carrier passes shop.money_format down as data-money-format, which the components render with
— avoiding the locale-dependent currency prefixes (e.g. US$) that Intl would otherwise
produce.