Repository navigation
Themes
Themes are data, not code. Every color, size, type size and timing of the window's chrome comes from one JSON file, themes/default.json. Edit it while the window is open and the chrome follows.
-
themes/default.jsonbeside the executable, else in its parent directory -
--theme <file.json>on the command line - The theme last chosen from the command palette, kept as
settings.jsonin the profile folder ({"theme": "<file>"}, see Running Sashfold) and read before the window opens - Every token has a built-in default; a missing or malformed token falls back to it, and each problem is named
Four more themes ship beside the default, each a plain theme file that overrides only the colors it changes: light.json (Sashfold Light), nord.json (Nord), solarized-dark.json (Solarized Dark) and high-contrast.json (High Contrast, with a two-pixel border). Every .json in the folder beside the shipped theme that parses clean and names itself is offered by the command palette (Ctrl+Shift+P, then Theme:) and by the main menu's Themes, where the one in use is checked — drop your own file in, and it is on the list under the name it gives itself. Choosing one puts it on at once, the window follows that file from then on (edit it and the chrome follows), and the choice is kept for the next start. A theme is one file: post it anywhere, and anyone can drop it beside theirs.
Colors — chrome-background, chrome-text, chrome-text-muted, chrome-border, tab-active-background, tab-inactive-background, tab-hover-background, address-background, address-text, address-border, accent, selection, find-highlight, find-current, hint-background, hint-text, button-hover-background, button-disabled-text, status-background, status-text, content-background, secure-indicator, insecure-indicator
Colors of a surface's own — whatever pops up over the window, a menu or the command palette, draws from popup-background, popup-border, popup-text, popup-text-muted (a shortcut, a row that is not highlighted), popup-disabled-text, popup-highlight and popup-highlight-text. A theme need not name them: one it leaves out takes that theme's own value of another token — chrome-background, address-border, chrome-text, chrome-text-muted, button-disabled-text, button-hover-background and chrome-text, in that order — never the built-in default, so a light theme written before menus existed has light menus. Every surface added from here on gets tokens of its own this way, each the counterpart of a key that Firefox and Chrome themes carry (popup, popup_border, popup_text, popup_highlight, popup_highlight_text for these), so that such a theme's colors have somewhere to land one to one.
The same goes for what the older tokens used to cover between them. The toolbar has toolbar-background, apart from the tab in front (from tab-active-background), and its buttons' glyphs toolbar-icon (from chrome-text) — the toolbar and icons of a browser theme. The tab in front has tab-text for its title (from chrome-text; the other tabs' stays chrome-text-muted) and tab-line, a line along its top edge, which is transparent unless a theme names it and sits under a container's stripe. A field with the focus — the address bar, the find box, the palette's — has address-background-focus, address-text-focus and address-border-focus (from address-background, address-text and accent), and the band over its selected text is address-selection (from selection): toolbar_field_focus, toolbar_field_text_focus, toolbar_field_border_focus and toolbar_field_highlight. None of the shipped themes names any of these, and each paints exactly as it did.
Metrics — tab-strip-height, tab-height, tab-max-width, tab-min-width, tab-corner-radius, tab-gap, toolbar-height, address-height, address-corner-radius, button-size, button-corner-radius, padding, border-width, status-height, find-height, devtools-height, scroll-step, tab-icon-size
Type — font-size, tab-font-size, status-font-size
Timings — tab-hover, tab-switch
New tab ("new-tab": { … }) — backgrounds, a folder of pictures (PNG, JPEG, GIF or BMP) written relative to the theme file, which the new-tab page rotates through in name order; rotate, how long each picture stays before the next fades in, in milliseconds (0 never rotates; 20000 by default). A theme that names no folder gets a gradient of its own colors.
Colors are written as #rrggbb or #rrggbbaa.
A unit test asserts that the shipped themes/default.json equals the built-in defaults token for token, so the file and the code cannot drift apart. The chrome goldens in CI (see Testing) are rendered from the same file.
Getting started
What works today
Measured
Design decisions
Testing and tools