Skip to Content
Custom CSSCSS Variable Reference

CSS Variable Reference

This page lists all CSS variables available for styling in DM Note.

Key Style Variables

CSS variables applied to key elements. Use with [data-state="inactive"] or [data-state="active"] selectors.

VariableDescriptionTypeExample
--key-radiusCorner roundness<length>8px, 50%
--key-bgBackground color and saved-image reset<color>#ff2b80
--key-bg-imageBackground image<image>linear-gradient(90deg, #f0f, #0ff)
--key-borderBorder and saved border-ring reset<border>2px solid #fff, none
--key-border-imageReplacement image for a saved ring<image>linear-gradient(90deg, #f0f, #0ff)
--key-paddingInner padding<length>0px, 3px
--key-text-colorText color<color>#ffffff
--key-text-imageReplacement image for saved text paint<image>linear-gradient(0deg, #f0f, #0ff)
--key-text-positionText paint box position<position>0% 0%
--key-text-sizeText paint box size<bg-size>auto, 100% 100%
--key-text-repeatText paint repeat<repeat-style>no-repeat
--key-shadowIdle and shared fallback shadow<shadow>0 4px 10px rgba(0,0,0,.28), none
--key-active-shadowActive shadow<shadow>0 3px 8px rgba(0,0,0,.32), none
--key-offset-xX offset in active state<length>0px, 2px
--key-offset-yY offset in active state<length>4px
--key-image-fitReplacement fit for the saved image<object-fit>cover, contain
--key-image-transformReplacement transform (offset, rotation, scale) for the saved image<transform>rotate(15deg) scale(1.2)
--key-image-zz-index of the image layer<integer>0, 3

With Inline Styles Priority disabled, property-panel colors, gradients, borders, typography, and shadows are low-priority defaults only. Setting --key-bg automatically removes a saved background gradient. Setting --key-border removes the saved gradient border ring and its spacing. The default border of an element with no border set is also a 1px gradient ring that fades from top to bottom, so it is replaced the same way. The ring is a child element, so a plain border rule on the key only changes the root border; reset it with --key-border or hide [data-key-element] > [data-gradient-border-ring]. Use --key-bg-image or the standard background property for a custom gradient. Setting --key-text-color (or a plain color rule on the label) removes a saved text gradient. For a custom text gradient, set --key-text-image together with --key-text-color: transparent. The glyph fill must be emptied for the gradient to show, so on a key without a saved gradient, --key-text-image alone stays hidden behind the opaque text color.

Image Layer

An image set in the properties panel renders as a child img[data-key-image-layer] of the key root, absolutely positioned inside the ring spacing (padding). The root carries data-key-image and the placement mode data-key-image-mode="replace|overlay".

  • replace (default): the app’s default background, border, shadow, and label are hidden and the image becomes the surface. A --key-border or padding from your CSS stays in effect, so the image draws inside it and is clipped by --key-radius. To show only the image, reset them yourself: [data-key-image-mode="replace"] { --key-border: none; --key-padding: 0 }.
  • overlay: the key surface, label, and counter render as usual and the image sits on top. The image inherits the key’s border-radius, and the root overflow is visible, so an offset, rotated, or scaled image may extend past the key. Set overflow: hidden to clip it.

Override the saved fit, transform, and stacking with --key-image-fit, --key-image-transform, and --key-image-z. With inline style priority enabled these three are promoted to inline declarations, so the --key-image-* variables do not apply; override object-fit, transform, and z-index directly with !important instead.

Usage Example

[data-state='inactive'] { --key-radius: 8px; --key-bg: #2a2a2a; --key-border: 2px solid #444; --key-text-color: #888; } [data-state='active'] { --key-radius: 8px; --key-bg: #ff2b80; --key-border: 2px solid #ff2b80; --key-text-color: #fff; --key-offset-x: 0px; --key-offset-y: 4px; }

Counter Style Variables

CSS variables applied to counter elements. Use with .counter[data-counter-state="..."] selectors.

VariableDescriptionTypeExample
--counter-colorText color and saved-fill reset<color>#ffffff
--counter-fill-imageText fill image<image>linear-gradient(90deg, #f0f, #0ff)
--counter-fill-clipFill clipping area<box>text, border-box
--counter-fill-positionFill background position<position>0% 0%, 4px 10px
--counter-fill-sizeFill background size<bg-size>auto, 100px 80px
--counter-fill-repeatFill repeat mode<repeat-style>no-repeat
--counter-text-fill-colorWebKit text fill color<color>transparent, currentcolor

Setting only --counter-color also disables a counter fill gradient saved in the app. Gradients created in the app are laid over the glyph ink box; use --counter-fill-position and --counter-fill-size to take over the placement. To create a CSS fill gradient, set all three fill variables:

.counter { --counter-fill-image: linear-gradient(90deg, #f0f, #0ff); --counter-fill-clip: text; --counter-text-fill-color: transparent; }

Usage Example

.counter[data-counter-state='inactive'] { --counter-color: #666; } .counter[data-counter-state='active'] { --counter-color: #ff2b80; }

Graph Style Variables

CSS variables available for graph elements. Disable Inline Styles Priority on the graph to control these via CSS. A graph with no border set draws the same default 1px gradient ring as keys; --graph-border resets it together with its spacing.

VariableDescriptionTypeExample
--graph-bgGraph background<color>rgba(17, 17, 20, 0.85)
--graph-borderBorder and saved border-ring reset<border>1px solid #7dd3fc, none
--graph-border-imageReplacement image for a saved ring<image>linear-gradient(90deg, #f0f, #0ff)
--graph-paddingGraph inner padding<length>0px, 3px
--graph-radiusGraph corner radius<length>10px
--graph-colorLine/bar drawing color<color>#86efac

Usage Example

.kps-graph { --graph-bg: rgba(7, 10, 18, 0.72); --graph-border: 1px solid rgba(125, 211, 252, 0.55); --graph-radius: 12px; --graph-color: #7dd3fc; }

Knob Style Variables

Disable Inline Styles Priority on a knob to use these variables. The custom class is on the position wrapper, so target .knob-class [data-knob-element] when applying standard properties directly to the visible surface. A knob with no border set draws the same default 1px gradient ring as keys; --knob-border resets it together with its spacing.

VariableDescriptionTypeExample
--knob-bgKnob background<color>#222
--knob-borderBorder and saved border-ring reset<border>2px solid #fff, none
--knob-border-imageReplacement image for a saved ring<image>linear-gradient(90deg, #f0f, #0ff)
--knob-paddingKnob inner padding<length>0px, 3px
--knob-radiusCorner radius<length>50%, 8px
--knob-shadowKnob shadow<shadow>0 4px 10px rgba(0,0,0,.3)
--knob-active-shadowTurning-state shadow<shadow>0 3px 8px rgba(0,0,0,.32)
--knob-indicatorCenter rotation indicator color<color>#fff
.volume-knob { --knob-bg: #17171b; --knob-border: none; --knob-indicator: #ff2b80; }

Sprite Style Variables

Reactive sprites render a single image layer that switches poses while its trigger keys are held. Placement and the rotation origin stay inline because the window bounds are computed from them; the appearance channels below are the ones you can replace. Disable Inline Styles Priority on the sprite to use them.

--sprite-transform replaces only the image’s local pose transform. The element-level placement rotation remains app-managed around the box center and is applied outside that pose transform.

VariableDescriptionTypeExample
--sprite-transformReplacement transform for the resolved pose (an onPress sprite then only swaps images)<transform>rotate(15deg) scale(1.2)
--sprite-transitionReplacement transition for the pose change (whileHeld only)<transition>transform 120ms ease-out
.left-hand [data-sprite-element] > img { --sprite-transition: transform 90ms cubic-bezier(0.2, 0, 0, 1); }

The image element already has the source aspect ratio and fills its box, so object-fit has nothing to change. Overriding the element size itself voids the pivot alignment of pose images.

Selector Reference

Key Selectors

SelectorDescription
[data-state="inactive"]All inactive keys
[data-state="active"]All active keys
[data-state="inactive"], [data-state="active"]All keys in all states
.classname[data-state="active"]Active state of keys with specific class

Counter Selectors

SelectorDescription
.counterAll counters
.counter[data-counter-state="inactive"]Inactive counters
.counter[data-counter-state="active"]Active counters
.classname .counter[data-counter-state="active"]Counter of keys with specific class

Graph Selectors

SelectorDescription
.graphClassNameStyle a specific graph container
.graphClassName svgStyle line graph SVG (stroke/fill)
.graphClassName > divStyle the inner plot area (line/bar shared)
.graphClassName > div > divStyle individual bars in bar mode

Knob Selectors

SelectorDescription
[data-knob-element]Every visible knob surface
[data-knob-state="inactive"]Idle knob surfaces
[data-knob-state="active"]Active knob surfaces
.knobClass [data-knob-element]A specific class’s knob surface
[data-knob-indicator]Center rotation indicator

Sprite Selectors

SelectorDescription
[data-sprite-element]Every sprite element box
[data-sprite-element] > imgThe sprite image layer
[data-sprite-state="inactive"]Sprites with no trigger key held
[data-sprite-state="active"]Sprites with a trigger key held (onPress sprites stay inactive)
.spriteClass [data-sprite-element]A specific class’s sprite

Standard CSS Properties

With Inline Styles Priority disabled, you can directly use standard visual properties such as the following. Element positioning remains app-managed; use --key-offset-x/--key-offset-y to move keys, graphs, and knobs.

Commonly Used Properties

[data-state='active'] { /* Shadow effect */ box-shadow: 0px 0px 8px #ff2b80; /* Text shadow */ text-shadow: 0px 0px 4px #ff2b80; /* Transition */ transition: all 0.1s ease-in-out; /* Font style */ font-size: 24px; font-weight: 700; font-family: 'Roboto', sans-serif; /* Filter */ filter: brightness(1.2); }

Notes

Using !important

Normal declarations lose to inline values only when Inline Styles Priority is enabled. In that mode, override the rendered CSS property itself with !important; adding it to a fallback custom property cannot beat an inline property declaration:

[data-state='active'] { background: #ff2b80 !important; box-shadow: 0px 0px 8px #ff2b80 !important; }

border: none !important clears only the root border. The gradient border ring (the app default and any saved ring) is a child element, so reset it with the border variable, which needs no !important, or hide the ring directly:

.my-key { --key-border: none; } /* or */ .my-key [data-gradient-border-ring] { display: none; }

Browser Compatibility

DM Note uses WebView2 on Windows and WKWebView on macOS. You can use modern CSS features supported by the WebView on the current operating system:

  • CSS Variables (Custom Properties) ✅
  • CSS Grid / Flexbox ✅
  • CSS Animations / Transitions ✅
  • CSS Filters ✅
  • backdrop-filter ✅
  • mix-blend-mode ✅

backdrop-filter does not work when the overlay background is transparent.

Inheritance and Specificity

  1. Global styles are applied first.
  2. Class selectors override global styles.
  3. More specific selectors take precedence.
/* Priority: 1 (lowest) */ [data-state='active'] { --key-bg: red; } /* Priority: 2 */ .blue[data-state='active'] { --key-bg: blue; } /* Priority: 3 (highest) */ .blue.special[data-state='active'] { --key-bg: purple; }