Skip to content

Commit 2590e94

Browse files
committed
Avoid theme flicker if system setting is dark
Previously, `@media (prefers-color-scheme: dark)` was only used in the `noscript` stylesheet, but that's the best way to immediately set the dark theme without any flickering. That is now integrated into the the main stylesheet. The flickering is still present if the user has a default system setting of light mode but explicitly set it to dark. Actually, this introduces flickering from dark to light if the user has a system setting of dark but an explicit override of light. So it goes both ways. I think this is a good tradeoff, most users will want the website to just follow the system setting. The `theme-switch.js` can also be simplified a little, since it's not necessary anymore to set the `data-theme` attribute if there is no explicit override.
1 parent d23b993 commit 2590e94

File tree

3 files changed

+88
-91
lines changed

3 files changed

+88
-91
lines changed

src/styles/app.scss

Lines changed: 83 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ $header-font: 'Alfa Slab One', serif;
66
// Switching theme will only work if JavaScript is enabled as well
77

88
// Default light theme
9-
:root, :root:not([data-theme]) {
9+
:root {
1010
--gray: #2a3439;
1111
--red: #a72145;
1212
--yellow: #ffc832;
@@ -33,32 +33,89 @@ $header-font: 'Alfa Slab One', serif;
3333
--rust-logo-filter: initial;
3434
}
3535

36-
// Dark theme
36+
// Dark theme variables
37+
:root {
38+
--dark-theme-gray: #2a3439;
39+
--dark-theme-red: #a72145;
40+
--dark-theme-yellow: #ffc832;
41+
--dark-theme-code-color: white;
42+
--dark-theme-code-bg-color: rgba(213, 203, 198, 0.05);
43+
--dark-theme-code-border-color: rgba(213, 203, 198, 0.25);
44+
--dark-theme-blockquote-color: rgb(195, 205, 210);
45+
--dark-theme-blockquote-bg-color: rgba(213, 203, 198, 0.05);
46+
--dark-theme-blockquote-left-border-color: rgb(195, 205, 210);
47+
--dark-theme-body-background-color: #181a1b;
48+
--dark-theme-body-foreground-color: #e8e6e3;
49+
--dark-theme-body-color: white;
50+
--dark-theme-div-brand-a-color: white;
51+
--dark-theme-white-elem-color: white;
52+
--dark-theme-white-elem-a: #d5cbc6;
53+
--dark-theme-nav-links-a: #d5cbc6;
54+
--dark-theme-publish-date-author: #d5cbc6;
55+
--dark-theme-section-header-h2-color: white;
56+
--dark-theme-theme-icon: #43484d;
57+
--dark-theme-theme-popup-border: #43484d;
58+
--dark-theme-theme-popup-bg: #141617;
59+
--dark-theme-theme-hover: #474c51;
60+
--dark-theme-theme-choice-color: #d5cbc6;
61+
--dark-theme-rust-logo-filter: drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);
62+
}
63+
64+
// Obey dark theme system preference unless data-theme is set explicitly
65+
@media (prefers-color-scheme: dark) {
66+
:root:not([data-theme]) {
67+
--gray: var(--dark-theme-gray);
68+
--red: var(--dark-theme-red);
69+
--yellow: var(--dark-theme-yellow);
70+
--code-color: var(--dark-theme-code-color);
71+
--code-bg-color: var(--dark-theme-code-bg-color);
72+
--code-border-color: var(--dark-theme-code-border-color);
73+
--blockquote-color: var(--dark-theme-blockquote-color);
74+
--blockquote-bg-color: var(--dark-theme-blockquote-bg-color);
75+
--blockquote-left-border-color: var(--dark-theme-blockquote-left-border-color);
76+
--body-background-color: var(--dark-theme-body-background-color);
77+
--body-foreground-color: var(--dark-theme-body-foreground-color);
78+
--body-color: var(--dark-theme-body-color);
79+
--div-brand-a-color: var(--dark-theme-div-brand-a-color);
80+
--white-elem-color: var(--dark-theme-white-elem-color);
81+
--white-elem-a: var(--dark-theme-white-elem-a);
82+
--nav-links-a: var(--dark-theme-nav-links-a);
83+
--publish-date-author: var(--dark-theme-publish-date-author);
84+
--section-header-h2-color: var(--dark-theme-section-header-h2-color);
85+
--theme-icon: var(--dark-theme-theme-icon);
86+
--theme-popup-border: var(--dark-theme-theme-popup-border);
87+
--theme-popup-bg: var(--dark-theme-theme-popup-bg);
88+
--theme-hover: var(--dark-theme-theme-hover);
89+
--theme-choice-color: var(--dark-theme-theme-choice-color);
90+
--rust-logo-filter: var(--dark-theme-rust-logo-filter);
91+
}
92+
}
93+
// Set dark theme based on explicit data-theme setting
3794
:root[data-theme='dark'] {
38-
--gray: #2a3439;
39-
--red: #a72145;
40-
--yellow: #ffc832;
41-
--code-color: white;
42-
--code-bg-color: rgba(213, 203, 198, 0.05);
43-
--code-border-color: rgba(213, 203, 198, 0.25);
44-
--blockquote-color: rgb(195, 205, 210);
45-
--blockquote-bg-color: rgba(213, 203, 198, 0.05);
46-
--blockquote-left-border-color: rgb(195, 205, 210);
47-
--body-background-color: #181a1b;
48-
--body-foreground-color: #e8e6e3;
49-
--body-color: white;
50-
--div-brand-a-color: white;
51-
--white-elem-color: white;
52-
--white-elem-a: #d5cbc6;
53-
--nav-links-a: #d5cbc6;
54-
--publish-date-author: #d5cbc6;
55-
--section-header-h2-color: white;
56-
--theme-icon: #43484d;
57-
--theme-popup-border: #43484d;
58-
--theme-popup-bg: #141617;
59-
--theme-hover: #474c51;
60-
--theme-choice-color: #d5cbc6;
61-
--rust-logo-filter: drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);
95+
--gray: var(--dark-theme-gray);
96+
--red: var(--dark-theme-red);
97+
--yellow: var(--dark-theme-yellow);
98+
--code-color: var(--dark-theme-code-color);
99+
--code-bg-color: var(--dark-theme-code-bg-color);
100+
--code-border-color: var(--dark-theme-code-border-color);
101+
--blockquote-color: var(--dark-theme-blockquote-color);
102+
--blockquote-bg-color: var(--dark-theme-blockquote-bg-color);
103+
--blockquote-left-border-color: var(--dark-theme-blockquote-left-border-color);
104+
--body-background-color: var(--dark-theme-body-background-color);
105+
--body-foreground-color: var(--dark-theme-body-foreground-color);
106+
--body-color: var(--dark-theme-body-color);
107+
--div-brand-a-color: var(--dark-theme-div-brand-a-color);
108+
--white-elem-color: var(--dark-theme-white-elem-color);
109+
--white-elem-a: var(--dark-theme-white-elem-a);
110+
--nav-links-a: var(--dark-theme-nav-links-a);
111+
--publish-date-author: var(--dark-theme-publish-date-author);
112+
--section-header-h2-color: var(--dark-theme-section-header-h2-color);
113+
--theme-icon: var(--dark-theme-theme-icon);
114+
--theme-popup-border: var(--dark-theme-theme-popup-border);
115+
--theme-popup-bg: var(--dark-theme-theme-popup-bg);
116+
--theme-hover: var(--dark-theme-theme-hover);
117+
--theme-choice-color: var(--dark-theme-theme-choice-color);
118+
--rust-logo-filter: var(--dark-theme-rust-logo-filter);
62119
}
63120

64121
html {

src/styles/noscript.scss

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,4 @@
11
// This stylesheet is used when the user agent has no JavaScript capabilities (or has it disabled)
2-
// Sets dark theme according to user agent preferences
3-
4-
// Default light theme
5-
:root, :root:not([data-theme]) {
6-
--gray: #2a3439;
7-
--red: #a72145;
8-
--yellow: #ffc832;
9-
--code-color: black;
10-
--code-bg-color: rgba(42, 52, 57, 0.05);
11-
--code-border-color: rgba(42, 52, 57, 0.25);
12-
--blockquote-color: black;
13-
--blockquote-bg-color: rgb(247, 249, 249);
14-
--blockquote-left-border-color: rgb(195, 205, 210);
15-
--body-background-color: white;
16-
--body-foreground-color: white;
17-
--body-color: rgb(34,34,34);
18-
--div-brand-a-color: black;
19-
--white-elem-color: black;
20-
--white-a: #2a3439;
21-
--nav-links-a: #2a3439;
22-
--publish-date-author: #2a3439;
23-
--section-header-h2-color: black;
24-
--rust-logo-filter: initial;
25-
}
26-
27-
// Dark theme (probed from user prefs)
28-
@media (prefers-color-scheme: dark) {
29-
:root, :root:not([data-theme]) {
30-
--gray: #2a3439;
31-
--red: #a72145;
32-
--yellow: #ffc832;
33-
--code-color: white;
34-
--code-bg-color: rgba(213, 203, 198, 0.05);
35-
--code-border-color: rgba(213, 203, 198, 0.25);
36-
--blockquote-color: rgb(195, 205, 210);
37-
--blockquote-bg-color: rgba(213, 203, 198, 0.05);
38-
--blockquote-left-border-color: rgb(195, 205, 210);
39-
--body-background-color: #181a1b;
40-
--body-foreground-color: #e8e6e3;
41-
--body-color: white;
42-
--div-brand-a-color: white;
43-
--white-elem-color: white;
44-
--white-elem-a: #d5cbc6;
45-
--nav-links-a: #d5cbc6;
46-
--publish-date-author: #d5cbc6;
47-
--section-header-h2-color: white;
48-
--rust-logo-filter: drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);
49-
}
50-
}
512

523
// Don't show the theme selector button when JavaScript is disabled
534
#theme-icon {

static/scripts/theme-switch.js

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
function changeThemeTo(val) {
44
if (val === "system") {
5-
setThemeToSystemPref();
5+
document.documentElement.removeAttribute("data-theme");
66
// delete explicit theme pref from browser storage
77
if (storageAvailable("localStorage")) {
88
localStorage.removeItem("blog-rust-lang-org-theme");
@@ -52,26 +52,15 @@ function handleBlur(event) {
5252
}
5353
}
5454

55-
function setThemeToSystemPref() {
56-
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
57-
document.documentElement.setAttribute("data-theme", "dark");
58-
} else {
59-
document.documentElement.setAttribute("data-theme", "light");
60-
}
61-
}
62-
6355
// close the theme dropdown if clicking somewhere else
6456
document.querySelector('.theme-icon').onblur = handleBlur;
6557

6658
// Check for saved user preference on load, else check and save user agent prefs
67-
let savedTheme = null;
6859
if (storageAvailable("localStorage")) {
69-
savedTheme = localStorage.getItem("blog-rust-lang-org-theme");
70-
}
71-
if (savedTheme) {
72-
document.documentElement.setAttribute("data-theme", savedTheme);
73-
} else {
74-
setThemeToSystemPref();
60+
const savedTheme = localStorage.getItem("blog-rust-lang-org-theme");
61+
if (savedTheme) {
62+
document.documentElement.setAttribute("data-theme", savedTheme);
63+
}
7564
}
7665

7766
// show the theme selector only if JavaScript is enabled/available

0 commit comments

Comments
 (0)