CSS Theming
A theme-aware SVG export carries no baked-in colors on its shapes. Instead, every bond, label, charge, and annotation is reclassified into a stable set of .mk-* classes, and a single scoped stylesheet inside the file supplies the light palette, the dark palette, and the switching logic. That makes the whole drawing restylable from your page with ordinary CSS. This page documents the class system, the dark-mode hooks, and the override patterns that work.
The mk class reference
Structural classes mark the drawing’s machinery. They are plain class rules with no !important, so any host selector can override them.
| Class | Targets |
|---|---|
mk-bond | Bond line strokes, including projection bonds and Newman circles |
mk-dash | Dashed (hash) bond lines; the dash pattern stays as an attribute |
mk-wedge | Solid wedge fills |
mk-wedge-outline | Hollow wedge outlines |
mk-double-x | Crossed double-bond marks |
mk-cap | Rounded bond end caps |
mk-vertex | Vertex dots where bonds meet at implicit carbons |
mk-aromatic | Aromatic ring circles |
mk-deloc-arc | Delocalization arcs |
mk-lp | Lone-pair dots and bars |
mk-radical | Radical dots |
mk-charge-label | Charge text and the plus/minus strokes inside circled charges |
mk-charge-circle | The ring around circled charges |
mk-halo | The page-colored halo painted behind atom labels |
mk-underlay | Page-colored masks that break crossing bonds |
mk-fo-text | HTML annotation text inside foreignObject blocks (uses color, not fill) |
mk-bg | The background rectangle, when background export is enabled |
mk-newman-bg | The page-colored circle fill in Newman projections |
mk-dflt-fill, mk-dflt-stroke | Fallback classes for shapes that used the default drawing color |
Color classes ride on top of the structural ones. Each element present in the drawing gets a class named after its symbol: mk-C, mk-O, mk-N, and so on, applied to atom label text (which also carries mk-atom), and inherited by that atom’s charges, lone pairs, and radicals. Rules are emitted only for elements actually used. Colors that match no color-scheme entry get a hashed custom class like mk-c0-k3v9, with an automatically derived dark counterpart; the random suffix prevents collisions when several SVGs are inlined on one page.
The !important policy: element and custom color rules carry !important; structural rules do not. The flag exists for multi-embed safety, because several inlined SVGs share page-scoped cascade order and a later file’s generic text rule could otherwise stomp an earlier file’s element colors. The practical consequence is in the recipes below.
How the injected CSS is built
Every rule is scoped to the export’s random root ID, but the ID is wrapped in :where(), which contributes zero specificity. An injected rule for .mk-bond therefore competes as if it were bare .mk-bond, and any host selector with higher specificity wins without fighting an ID. A representative excerpt:
/* light */:where(#molkit-a1b2c) .mk-bond { stroke: #000000; }:where(#molkit-a1b2c) .mk-halo { fill: var(--mk-page-bg, #ffffff); }:where(#molkit-a1b2c) .mk-O, :where(#molkit-a1b2c) text.mk-O { fill: #ff0000 !important; color: #ff0000 !important; stroke: none; }
/* dark, inside @media (prefers-color-scheme: dark) */:where(#molkit-a1b2c:not(.mk-light, .mk-light *)) .mk-bond { stroke: #e0e0e0; }:where(#molkit-a1b2c:not(.mk-light, .mk-light *)) .mk-O, :where(#molkit-a1b2c:not(.mk-light, .mk-light *)) text.mk-O { fill: #ef4444 !important; color: #ef4444 !important; stroke: none; }The light values come from your active color scheme at export time (see color schemes); gradient bonds keep their gradients, with dark mode remapping the stop colors by attribute selector.
Dark mode: the three-state system
Theme-aware exports resolve dark mode in three states.
- Default: follow the OS. The dark palette ships inside a
prefers-color-scheme: darkmedia query and activates with the system setting. This is what you get in animgtag with zero work. - Force dark: class
mk-dark. Addmk-darkto the inlined SVG or any ancestor and the dark palette applies regardless of the OS. The same dark rules are emitted a second time under an.mk-darkancestry scope, appended last so they win the cascade at equal specificity. - Force light: class
mk-light. Addmk-lightto the SVG or any ancestor and the media query is suppressed (its scope selector excludes.mk-lightancestry), so the export stays light even on a dark OS.
This is exactly what a site with its own theme toggle needs: drive the classes from your toggle and embedded drawings follow the site, not the OS.
<button id="theme-toggle">Toggle theme</button><div class="content"> <!-- inlined theme-aware Molkit SVGs anywhere below documentElement --></div><script> const root = document.documentElement; let dark = window.matchMedia('(prefers-color-scheme: dark)').matches; function applyTheme() { root.classList.toggle('mk-dark', dark); root.classList.toggle('mk-light', !dark); // ...flip your site's own theme class here too } document.getElementById('theme-toggle').addEventListener('click', () => { dark = !dark; applyTheme(); }); applyTheme();</script>Animated exports carry the same three hooks. Exports made before the class hooks shipped respond only to the media query; re-export if you need toggle support. See animations for the playback side.
Override recipes
Recolor all bonds. Structural classes have no !important, so one wrapper class of specificity is enough. Cover the fill-based bond classes too:
.figure .mk-bond, .figure .mk-dash, .figure .mk-wedge-outline { stroke: #1e3a5f; }.figure .mk-wedge { fill: #1e3a5f; stroke: #1e3a5f; }.figure .mk-cap, .figure .mk-vertex, .figure .mk-double-x { fill: #1e3a5f; }Recolor one element site-wide. Element rules use !important, so yours must as well, and it must match both the text and stroke variants:
svg .mk-O, svg text.mk-O { fill: #d97706 !important; color: #d97706 !important; }svg line.mk-O, svg path.mk-O { stroke: #d97706 !important; }Remember the export’s dark block also sets these with !important; add a .mk-dark variant of your rule if you want the override to survive forced dark.
Match the page background. Halos and underlays paint with --mk-page-bg, which defaults to white in light mode and a near-black in dark mode (the background rect itself goes transparent in dark mode). If your dark page uses a different background, set the variable so label halos do not show as off-color rectangles:
.mk-dark svg { --mk-page-bg: #111827; }Fonts
Theme-aware CSS controls color; text fidelity is a separate axis with four strategies. Full details at font embedding.
| Strategy | Host page must provide | Text selectable |
|---|---|---|
Default: a Google Fonts @import is injected for non-local web fonts used | Network access to the fonts CDN | Yes |
Embed fonts for offline use: font binaries inlined as data URIs | Nothing | Yes |
Mobile-safe rendering: a Liberation Sans glyph subset embedded as an Arial-metric fallback | Nothing | Yes |
Convert labels to paths: labels become vector outlines | Nothing | No |
Every export ends with an ID-scoped print block that forces bonds to solid black at a heavier stroke and hides the background rectangle, so drawings print cleanly from any page that embeds them.