Themes
How the light and dark themes color everything — the page, highlighted code, diagrams and widgets — from one set of tokens, how a reader switches between them, and how far a page can change the look. It is a task and reference article under the viewer.
The tokens
The viewer has a light and a dark theme. Which one shows is the one the
reader switched to with the theme switch, or — until they
switch, and on a page without one — the system setting
(prefers-color-scheme). The chosen theme is set on the page as
data-theme="light" or data-theme="dark" on <html>, before it paints, and
every dark value hangs off that. The page's colors come from seven tokens,
defined in assets/style.css:
| Token | Used for | Light | Dark |
|---|---|---|---|
--background |
page background | #ffffff |
#000000 |
--surface |
sidebar, quotes | #f5f5f7 |
#1d1d1f |
--text |
body text | #1d1d1f |
#f5f5f7 |
--muted |
secondary text, group headings | #6e6e73 |
#a1a1a6 |
--border |
rules, borders, hover | #d2d2d7 |
#424245 |
--accent |
links, the current sidebar entry | #0066cc |
#2997ff |
--code |
code background | #f5f5f7 |
#1d1d1f |
Seven more tokens color highlighted code. Their values are Xcode's default light and dark palettes:
| Token | Light | Dark |
|---|---|---|
--syntax-keyword |
#9b2393 |
#ff7ab2 |
--syntax-string |
#c41a16 |
#ff8170 |
--syntax-number |
#1c00cf |
#d9c97c |
--syntax-comment |
#5d6c79 |
#7f8c98 |
--syntax-type |
#0b4f79 |
#dabaff |
--syntax-function |
#326d74 |
#67b7a4 |
--syntax-attribute |
#815f03 |
#fd8f3f |
Two font tokens, --font and --font-mono, are shared by both themes. A
theme is a set of values for these tokens. A few colors are fixed rather than
taken from a token: the text of the current sidebar entry (white); the red
(#d70015) of diagram errors, comment errors, the problems bar and broken-link
marks. How the tokens reach highlighted code and diagrams is on
How themes reach code and diagrams.
Choosing a theme
Every page — a site's, a doc, a deck — has a theme switch in its top-right
corner: one small icon button that switches between light and dark. It shows
the theme a click switches to — a moon in light, a sun in dark. Until the reader
clicks it, the page follows their system setting; after, the browser remembers
the theme they switched to, for the address it was made on. A switch changes
everything drawn from the tokens at once: the page, highlighted code, diagrams
and widgets. On a site with a navbar the button sits at the right end of the
bar. It is never printed, and a deck hides it in fullscreen. A document file
turns it off with theme-selector: false; the page then follows the system
setting, as before the switch existed.
Changing the look
The themes can't be changed per document. A document file has no theme
field — any field its kind doesn't have stops devpage with an error — and the
stylesheet is compiled into the binary, so there is no custom stylesheet option
and no way to add a third theme without changing assets/style.css and
rebuilding devpage.
What a page can do is carry its own CSS. Raw HTML passes through, so a
<style> block in a page's Markdown is part of that page:
It applies while that page is shown — to the whole frame, the sidebar
included, since a <style> element isn't scoped to the article — and to no
other page: opening another page, by a link or a fresh load, replaces the
page content and the <style> with it. A token set this way, as above,
recolors everything that uses it, in both themes, because the rule comes after
the built-in stylesheet; scope it to :root[data-theme="dark"] (or "light")
to change one theme only — a @media (prefers-color-scheme: …) rule would
follow the system, not the reader's choice. Nothing checks such CSS, and it
rides along with the page's content, so use it for one page's needs rather
than as a theme.
Topics
- How themes reach code and diagrams
— the
hl-classes highlighted code carries, and the pele variables diagrams draw with.