tl;dr
- **default to the user's preference, not light.**
- if either, set *both* `color` *and* `background-color`
- include a `<meta name="color-scheme" content="light dark">` tag
- in js, use `window.matchMedia( "( prefers-color-scheme: dark )" ).matches`
----
i prefer dark mode
others prefer light mode
that's fine
but can we please respect the user's preferences on *first load* ?
the ideal is [ no /minimal js, default to user preference, option to switch theme ]
without offering the switch option, the simplest style implementation is
```css
:root { --foreground: black; --background: white; --link-fg: blue ; --link-bg: white; }
@media( prefers-color-scheme: dark ) {
:root { --foreground: white; --background: black; --link-fg: green ; --link-bg: black; }
}
/* ... */
body {
color: var( --foreground );
background-color: var( --background );
}
a {
color: var( --link-fg );
background-color: var( --link-bg );
}
/* ... */
```
alternatively:
```css
:root {
--foreground : light-dark( black, white );
--background : light-dark( white, black );
--link-fg : light-dark( blue , green );
--link-bg : light-dark( white, black );
}
```
.. aside #1: if either the color or the background-color is set, *both* should be set
aside #0: if your site supports both light and dark preferences, add a meta tag:
```html
<meta name="color-scheme" content="light dark" />
```
this sets `color-scheme`, [font-]`color`, and `background-color` appropriately for both light and dark modes,
particularly useful for minimal pages with *no css*. ( hey, nginx index page! )
.. may also help with flash-of-white, tho not certain..
okay, back on task..
the above simple style doesn't allow a mechanism for a user
to easily swap light/dark style of a site without changing their preferences..
fine; so all the styles get factored into classes for html or body..
.. recommend `<html>` ( `document.documentElement` ) over `<body>` ( `document.body` )
.. on small pages, the body may not fill the full viewport (html);
.. can use `html { height: 100vh; } body { min-height: 100vh; }`
```css
```
fair enough;
for this approach, js is already in use;
add a check to `window.matchMedia( "( prefers-color-scheme: dark )" ).matches` on the first load,
and update the light-dark element-class as appropriate;
if desired, use `localStorage` to persist the site-level preference.
or `sessionStorage` for a site-level preference with browser-session duration.
**********************************************************************************
** just make the *initial* load respect the user's default preferences. please. **
**********************************************************************************
summary
- when setting `color` or `background-color`, set *both* `color` *and* `background-color`
- when supporting both light and dark, add a `<meta name=color-scheme content="light dark">` tag
- if you want your site to allow switching between light and dark mode, default to the user's preference, not light.
- default to the user's preference using `window.matchMedia( "( prefers-color-scheme: dark )" ).matches`
- persist changes using `localStorage`
- respond to user preference changes using `window.matchMedia( "( prefers-color-scheme: dark )" ).addEventListener( "change", function() { ... } )`
- `canvas` and `canvasText` automatically respect `color-scheme` which respects user-preference
document.addEventListener( "DOMContentLoaded", function onReady() { ... } );
.. or just use a module script tag `<script type="module" src="..."></script>` which only executes after `DOMContentLoaded`
```
```
yes, this code is verbose and indirect;
it's purpose is to demonstrate explicitly how to do the bare minimum with all systems.