Skip to Content
Custom CSSIntroduction

Custom CSS Guide

DM Note allows you to freely customize key and counter styles through custom CSS. You can implement various styles like neon signs, minimal designs, game themes, and more.

If custom CSS is enabled and using a file path, changes are automatically reapplied when you modify/save the CSS file.

Where It Applies

The overlay window and the OBS browser source receive the CSS file as is. In the main editor window it applies only to the grid preview (keys, counters, graphs, knobs, and plugin elements) and to the counter animation editor preview; app UI such as the settings panel and toolbar is not reached by your selectors. To make that work, every selector in the main window is confined to the preview area, and rules written on body or :root apply to the preview area itself. The prefix used for confinement does not change specificity, so ordinary rules cascade the same way on the canvas and in the overlay. A few limits apply to the main window only:

  • @keyframes names are prefixed automatically so they never collide with the app’s own animations, and names written directly in animation or animation-name are rewritten to match. Only plain identifiers (letters, digits, hyphens) are supported; definitions whose name needs quoting or equals a reserved word such as linear are left out of the main window. Animation names passed through a CSS variable (var()) are not rewritten either and will not run in the main window.
  • Stylesheets pulled in with @import are fetched by the app and confined to the preview area the same way. A sheet that cannot be fetched (offline, error response, over 1 MiB, nested more than three levels deep) is skipped in the main window only. localhost and private-network imports work without a prompt; explicit cloud metadata URLs are rejected. If an imported sheet and its parent declare the same @namespace prefix with different URLs, the parent’s declaration wins in the main preview.
  • @font-face family names receive private names in the main window. Matching references in CSS rules, @font-feature-values, and static custom properties are rewritten as well, so a web font still works in the grid preview without changing app UI that uses the original family name. A name added later by JavaScript or an element’s inline style cannot be rewritten for the main preview. @counter-style, @font-palette-values, and unrelated @font-feature-values rules pass through unchanged for compatibility. @property can collide with names the app registers and is ignored in the main window.
  • Selectors that target siblings of body, such as body + .x, cannot be moved inside the preview area and are ignored in the main window. The same applies to the nested form, such as body { & ~ .x { } }.

None of these limits apply to the overlay or OBS, where the CSS file is used as is.

Basic Concepts

CSS Variable System

DM Note uses CSS Variables (Custom Properties) to control styles. This allows you to easily change core styles of keys and counters without complex selectors.

/* Key style variables */ [data-state="active"] { --key-radius: 8px; /* Corner roundness */ --key-bg: #ff2b80; /* Background color */ --key-border: 2px solid #fff; /* Border */ --key-text-color: #fff; /* Text color */ }

State-based Styling

Keys and counters have two states:

StateSelectorDescription
Inactive[data-state="inactive"]Key not pressed
Active[data-state="active"]Key being pressed

For counters:

  • [data-counter-state="inactive"]: Key not pressed
  • [data-counter-state="active"]: Key being pressed

Applying CSS Files

  1. Create a CSS file with your desired styles.
  2. Go to the Settings tab and click Manage CSS.
  3. Turn on the Enable toggle, then click Import CSS File.
  4. Select your CSS file (.css, up to 1 MiB). Previously imported files stay in the panel list, ready to re-apply with one click.

Per-Tab CSS

Each key tab can override the global CSS with its own file. Right-click the grid and choose the tab CSS menu to open the popover:

  • Import: pick a CSS file that applies to the current tab only.
  • History list: files already imported in the custom CSS panel appear below the file actions; click Apply on an entry to use it for this tab.
  • Export: save the CSS currently registered on this tab back to a .css file. This is handy when the original file was moved or deleted, since the tab keeps its own copy of the content.
  • The toggle at the top enables or disables the tab override without removing it.

Tab CSS is applied only while the global Custom CSS toggle is on.

Quick Start Example

Here’s a simple neon sign style example:

/* Global key styles */ [data-state="inactive"], [data-state="active"] { --key-radius: 6px; font-size: 24px; font-weight: 700; } /* Inactive state */ [data-state="inactive"] { --key-bg: transparent; --key-border: 3px solid #474244; --key-text-color: #474244; } /* Active state - neon effect */ [data-state="active"] { --key-bg: transparent; --key-border: 3px solid #ff2b80; --key-text-color: #ff2b80; text-shadow: 0px 0px 3px #ff2b80; box-shadow: 0px 0px 4px #b3245d, 0px 0px 4px #b3245d; }

Next Steps