Obsidian CSS variables explained: how themes use color tokens and design tokens
A technical deep-dive into Obsidian CSS variables and design tokens: how themes define backgrounds, text colors, accents, fonts, and spacing for custom snippets.
What are Obsidian CSS variables
Obsidian themes are built on a system of CSS custom properties, commonly called CSS variables. These variables act as design tokens — named values for colors, fonts, spacing, and border radii that the Obsidian interface reads to render every part of the application. When you change a theme, Obsidian redefines this entire token set, and every pane, button, and text element updates automatically.
The token system is organized into functional groups. Background variables control the surfaces: --background-primary for the main editor, --background-secondary for sidebars, --background-modifier for hover states and selected items. Text variables control readability: --text-normal for body copy, --text-muted for secondary information, --text-accent for highlighted terms. Accent variables define interactive elements: --interactive-accent for links and active states, --interactive-hover for hover backgrounds.
Understanding the variable naming convention makes any theme predictable. Variables prefixed with --background- control surfaces, --text- controls readability, --interactive- controls interactions, --font- controls typography, and --color- provides semantic accent colors. Once you recognize these patterns, you can read a theme CSS file like a design system specification.
Core typography variables
The --font-text variable sets the body font family used in the editor and reading view. Themes can define a stack of fonts, such as 'Inter', system-ui, sans-serif, so that the browser falls back gracefully if the primary font is not installed. The --font-text-size variable controls the base body text size, typically 16px.
Headings are controlled separately. --font-heading sets the heading font family, which can differ from the body font for visual contrast. --h1-size through --h6-size control individual heading sizes, and --h1-weight through --h6-weight control boldness. Some themes also define --h1-color through --h6-color for colored heading levels, creating visual hierarchy without relying on size alone.
Code typography uses --font-monospace for code blocks and inline code. This variable is often set to a developer-friendly monospace font like 'JetBrains Mono', 'Fira Code', or 'SF Mono'. The --code-size variable controls code text size, which is usually slightly smaller than body text to distinguish code from prose.
Semantic color tokens for callouts and UI
Obsidian defines semantic color tokens for callout types: --callout-default, --callout-info, --callout-tip, --callout-success, --callout-warning, and --callout-danger. Each token controls the background, border, and icon color for that callout variant. A well-designed theme differentiates these callout types clearly so users can scan a note and instantly understand the tone of each block.
Checkbox styling uses --checkbox-color for unchecked boxes and --checkbox-color-hover for hover states. Completed checkboxes are controlled by dedicated variables that apply a distinct color and opacity, so done items recede visually without disappearing entirely. Some themes extend checkbox variables with custom states for recurring tasks, project milestones, and daily habits.
Tag variables include --tag-color and --tag-background for inline tags, and --tag-border for optional border styling. These variables make tags visually distinct from regular text, which is especially important in PKM vaults where tags are a primary navigation mechanism. Themes with strong tag styling often expose additional variables for tag hover states and active selection.
How to use variables in your own snippets
The simplest approach to CSS snippets is overriding an existing theme variable. If a theme's heading color is too subtle, add --h1-color: #e2e8f0; to your snippet and every H1 in your vault updates. This works because CSS variables cascade: your snippet values override the theme's defaults without touching the theme CSS file.
For more advanced customizations, use Obsidian's class-based selectors in combination with variables. For example, .markdown-rendered h1 { --h1-color: #c084fc; } changes only reading view headings while leaving source mode untouched. This is useful for users who want different styling in reading and editing modes.
To discover which variables a theme exposes, open the theme CSS file from the theme's GitHub repository or inspect the computed styles in Obsidian's developer tools. The community also maintains reference lists of standard Obsidian variables that work across all themes. Start with the default Obsidian variable reference and explore from there.
Theme development resources
The official Obsidian theme documentation provides the complete list of CSS variables that Obsidian reads. This is the authoritative reference for anyone building or modifying themes. The documentation covers all variable categories: backgrounds, text, accents, fonts, code, callouts, tags, checkboxes, and plugin-specific tokens.
For theme authors, the Obsidian sample theme repository on GitHub provides a complete starting template with all standard variables pre-defined. You can clone the repository, modify the variable values, and test your theme locally before submitting it to the community store. The template includes dark and light mode support out of the box.
Community resources like the Obsidian CSS Discord channel and the theme development forum are active spaces for troubleshooting variable conflicts, learning advanced CSS techniques, and sharing snippet recipes. Many theme authors are active in these communities and provide direct support for customization questions.