Colors: Allow setting the color scheme explicitly

In addition to the color scheme changing based on the system setting, enable
setting the color scheme explicitly by adding a color-scheme="light | dark" attribute
on the <html> element.

Doing this was a bit tricky. I originally implemented the grayscale ramp by
reversing it when prefers-color-scheme: dark. This was convenient, but meant that
setting the color scheme explicitly didn't work.

Along the way I discovered the light-dark() CSS function. Deploy that as the preferred
style if the browser supports it. Otherwise, fall back on the prefers-color-scheme
media queries. This function only works if color-scheme: light dark is set on the
:root element.
This commit is contained in:
Eryn Wells 2024-07-27 22:59:56 -07:00
parent cb8ad426d5
commit 8a00cc6de9
8 changed files with 53 additions and 29 deletions

View file

@ -22,29 +22,48 @@
--lilac: rgb(187 121 245); --lilac: rgb(187 121 245);
--purple: rgb(197 141 244); --purple: rgb(197 141 244);
--background-color: var(--gray7); color-scheme: light dark;
--hr-color: var(--gray1);
--text-color: var(--text-color-primary);
--text-color-primary: var(--gray1);
--text-color-secondary: var(--gray4);
--text-color-light: var(--gray5);
} }
@media (prefers-color-scheme: dark) {
@media screen and (prefers-color-scheme: light) {
:root { :root {
/* Reverse the grayscale ramp in dark mode. */ --background-color: var(--gray7);
--gray7: rgb(17 19 28); --hr-color: var(--gray1);
--gray6: rgb(28 32 48); --text-color-primary: var(--gray1);
--gray5: rgb(53 59 82); --text-color-secondary: var(--gray4);
--gray4: rgb(86 96 121); --text-color-light: var(--gray5);
--gray3: rgb(139 144 164);
--gray2: rgb(206 207 214);
--gray1: rgb(255 253 249);
} }
} }
@media screen and (prefers-color-scheme: dark) {
:root {
--background-color: var(--gray1);
--hr-color: var(--gray7);
--text-color-primary: var(--gray7);
--text-color-secondary: var(--gray5);
--text-color-light: var(--gray4);
}
}
:root {
--background-color: light-dark(var(--gray7), var(--gray1));
--hr-color: light-dark(var(--gray1), var(--gray7));
--text-color-primary: light-dark(var(--gray1), var(--gray7));
--text-color-secondary: light-dark(var(--gray4), var(--gray5));
--text-color-light: light-dark(var(--gray5), var(--gray4));
}
:root[color-scheme="dark"] {
color-scheme: only dark;
}
:root[color-scheme="light"] {
color-scheme: only light;
}
body { body {
background-color: var(--background-color); background-color: var(--background-color);
color: var(--text-color); color: var(--text-color-primary);
} }
hr { hr {

View file

@ -92,7 +92,7 @@ sup {
small, small,
.text--small .text--small
{ {
color: var(--gray4); color: var(--text-color-secondary);
font-weight: normal; font-weight: normal;
font-size: var(--text-s); font-size: var(--text-s);
letter-spacing: 0.01em; letter-spacing: 0.01em;

View file

@ -18,7 +18,7 @@
} }
figcaption { figcaption {
color: var(--gray4); color: var(--text-color-secondary);
font-weight: normal; font-weight: normal;
font-size: var(--text-xs); font-size: var(--text-xs);
letter-spacing: 0.01em; letter-spacing: 0.01em;

View file

@ -11,7 +11,7 @@ blockquote {
--border-width: var(--space-xs); --border-width: var(--space-xs);
--inline-padding: var(--space-l); --inline-padding: var(--space-l);
border-inline-start: var(--border-width) solid var(--gray4); border-inline-start: var(--border-width) solid var(--text-color-light);
margin-inline: 0 var(--inline-padding); margin-inline: 0 var(--inline-padding);
padding-inline-start: calc(var(--inline-padding) - var(--border-width)); padding-inline-start: calc(var(--inline-padding) - var(--border-width));
} }

View file

@ -8,7 +8,7 @@
**************/ **************/
.site-footer { .site-footer {
border-top: 2px dashed var(--gray6); border-top: 2px dashed var(--text-color-light);
color: var(--text-color-secondary); color: var(--text-color-secondary);
font-size: var(--text-s); font-size: var(--text-s);
grid-column: main-start / main-end; grid-column: main-start / main-end;

View file

@ -2,11 +2,10 @@
# COMPONENT: SITE HEADER # COMPONENT: SITE HEADER
*************************/ *************************/
.site-header { @media (prefers-color-scheme: dark) {
--color-nav-separator: var(--gray6); .site-header {
--color-nav-separator: var(--gray6);
font-family: var(--font-family-monospace); }
margin-block: var(--space-m) var(--space-xl);
} }
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
@ -15,14 +14,21 @@
} }
} }
.site-header {
--color-nav-separator: light-dark(var(--gray6), var(--gray4));
font-family: var(--font-family-monospace);
margin-block: var(--space-m) var(--space-xl);
}
.site-header__content { .site-header__content {
border-bottom: 2px dashed var(--gray6); border-bottom: 2px dashed var(--color-nav-separator);
gap: var(--space-l); gap: var(--space-l);
grid-column: main-start / main-end; grid-column: main-start / main-end;
padding-bottom: var(--space-xs); padding-bottom: var(--space-xs);
.site-header__title { .site-header__title {
color: var(--gray1); color: var(--text-color-primary);
font-size: var(--text-m); font-size: var(--text-m);
font-weight: normal; font-weight: normal;
letter-spacing: 0.05em; letter-spacing: 0.05em;

View file

@ -15,7 +15,6 @@
.codeblock { .codeblock {
color: var(--foreground); color: var(--foreground);
background-color: var(--background); background-color: var(--background);
border: 1px solid var(--gray6);
font-family: var(--font-family-monospace); font-family: var(--font-family-monospace);
grid-column: gutter-start / gutter-end; grid-column: gutter-start / gutter-end;
overflow: auto; overflow: auto;

View file

@ -26,7 +26,7 @@
} }
.page-header__subtitle { .page-header__subtitle {
color: var(--gray3); color: var(--text-color-secondary);
font-size: var(--text-m); font-size: var(--text-m);
} }