Dynamic Modes
Dynamic modes allow us to manage light and dark color schemes by toggling a single custom property. Modes inputs “cascade” such that HTML modes (set here) take precedence, followed by the user mode (which can be set in Javascript), and finally the operating-system or browser color-scheme preferences.
OS modes
[data-ccs='root'] {
--ccs-mode--os: 1;
@media (prefers-color-scheme: dark) {
--ccs-mode--os: -1;
}
}
On the CCS root,
we check the user’s color-scheme preference,
to set --ccs-mode--os
,
which provides a dynamic default value.
cascading modes
[data-ccs-colors] {
--ccs-mode--cascade: var(--ccs-mode--html, var(--ccs-mode--user, var(--ccs-mode--os, 1)));
--ccs-mode: var(--ccs-mode--cascade, 1);
--ccs-mode--zero: calc((var(--ccs-mode) + 1) * 0.5);
--ccs-invert: calc(-1 * var(--ccs-mode));
--ccs-invert--zero: calc((var(--ccs-invert) + 1) * 0.5);
}
Each instance of the color system
will re-calculate the “cascade” of mode origins
to determine the final --ccs-mode
(1
for a “light” background and -1
for a “dark” background),
along with a --ccs-invert
which reverses the numbers.
Both have *--zero
versions that change the numbering
(0
for a “dark” background)
for use in on/off toggles.
light mode
[data-ccs-colors='light'] {
--ccs-mode--html: 1;
}
Set “light” mode explicitly in HTML.
dark mode
[data-ccs-colors='dark'] {
--ccs-mode--html: -1;
}
Set “dark” mode explicitly in HTML.
invert
[data-ccs-colors='invert'] {
--ccs-mode: calc(-1 * var(--ccs-mode--cascade, 1));
}
Dynamic inversion will flip light/dark mode in a nested context (one level deep).