Skip to content

Theming

Every value is a CSS custom property. Re-skin without forking.

Everything the default theme paints is a --blasdoc-* custom property. CSS, SCSS or Tailwind can re-skin it without forking anything.

Applying the content styles

html
<main blasdocContentStyles>
  <router-outlet />
</main>

That one directive brings the typography, lists, tables, blockquotes and links. Without it you get Blasdoc's structure and none of its opinions, which is a legitimate choice.

Overriding a token

css
:root {
  --blasdoc-code-radius: 0;
  --blasdoc-code-bg: #0d1117;
  --blasdoc-content-accent: oklch(0.62 0.19 264);
  --blasdoc-table-head-bg: #161b22;
}

The tokens

GroupExamples
Content--blasdoc-content-fg, --blasdoc-content-muted, --blasdoc-content-accent, --blasdoc-content-border, --blasdoc-content-line-height, --blasdoc-content-h1-size
Tables--blasdoc-table-border, --blasdoc-table-head-bg, --blasdoc-table-head-fg, --blasdoc-table-stripe, --blasdoc-table-hover, --blasdoc-table-padding
Code--blasdoc-code-bg, --blasdoc-code-fg, --blasdoc-code-border, --blasdoc-code-radius, --blasdoc-code-padding
Tabs--blasdoc-tab-padding, --blasdoc-tab-active
Preview--blasdoc-preview-padding, --blasdoc-preview-bg
Callouts--blasdoc-callout-note, --blasdoc-callout-warning, --blasdoc-callout-danger, --blasdoc-callout-success, and a -label for each
Focus--blasdoc-focus, --blasdoc-focus-width
Type--blasdoc-font, --blasdoc-mono

Typography

Prose is set in --blasdoc-font, which is inherit: rendered Markdown takes the type of the page it sits in, so Blasdoc never overrides a host application's typeface. Code is different — a code block has to be monospaced, so --blasdoc-mono names a stack. It leads with Geist Mono, Blasdoc's own type, and falls through to the platform monospace stack when the project does not ship it.

css
:root {
  --blasdoc-font: 'Inter Variable', system-ui, sans-serif;
  --blasdoc-mono: 'JetBrains Mono', ui-monospace, monospace;
}

Blasdoc ships no font files and loads none: naming a family is all a theme does. This site self-hosts Geist and Geist Mono through @fontsource-variable/geist, which is the approach we recommend — no third-party request on a prerendered page.

Dark mode

Two ways, both supported at once: prefers-color-scheme for visitors who never touch a switch, and [data-theme] for applications that own the choice.

html
<html data-theme="dark">

Setting data-theme wins over the media query, which is what a theme toggle needs.

data-theme is not reserved to the root: any element may carry it, and the scheme applies to that subtree alone. That is how a page shows one scheme inside the other — the theme generator previews a dark theme on a light page this way.

html
<div data-theme="dark">
  <!-- dark, whatever the page around it is -->
</div>

With Tailwind

The tokens are plain custom properties, so Tailwind's own values drop straight in:

css
:root {
  --blasdoc-code-bg: var(--color-zinc-900);
  --blasdoc-content-accent: var(--color-indigo-400);
}

Replacing the UI entirely

Skip provideBlasdocTheme() and register your own components, or replace one at a time — see Built-in components and Headless directives.