Skip to content

Commit d7c9ce9

Browse files
docs: fix dark mode background flash (#2825)
Fixes #2823 (comment)
1 parent b1f2a98 commit d7c9ce9

File tree

3 files changed

+33
-23
lines changed

3 files changed

+33
-23
lines changed

www/islands/ThemeToggle.tsx

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,19 @@
1-
import { useEffect, useState } from "preact/hooks";
1+
import { useState } from "preact/hooks";
22
import { IS_BROWSER } from "fresh/runtime";
33

44
export default function ThemeToggle() {
5-
const getPreferredTheme = () => {
5+
const [theme, setTheme] = useState(() => {
66
if (!IS_BROWSER) return "light";
7-
const storedTheme = localStorage.getItem("theme");
8-
if (storedTheme) return storedTheme;
9-
return window.matchMedia("(prefers-color-scheme: dark)").matches
10-
? "dark"
11-
: "light";
12-
};
13-
14-
const [theme, setTheme] = useState(getPreferredTheme);
15-
16-
useEffect(() => {
17-
document.documentElement.classList.remove("light", "dark");
18-
document.documentElement.classList.add(theme);
19-
document.documentElement.setAttribute("data-theme", theme);
20-
localStorage.setItem("theme", theme);
21-
}, [theme]);
7+
return document.documentElement.dataset.theme ?? "light";
8+
});
229

2310
const toggleTheme = () => {
24-
setTheme((prev) => (prev === "light" ? "dark" : "light"));
11+
setTheme((prev) => {
12+
const theme = prev === "light" ? "dark" : "light";
13+
document.documentElement.setAttribute("data-theme", theme);
14+
localStorage.setItem("theme", theme);
15+
return theme;
16+
});
2517
};
2618

2719
return (

www/routes/_app.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { define } from "../utils/state.ts";
33

44
export default define.page(function App({ Component, state, url }) {
55
return (
6-
<html lang="en" class="dark" data-theme="dark">
6+
<html lang="en">
77
<head>
88
<meta charset="utf-8" />
99
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
@@ -23,6 +23,7 @@ export default define.page(function App({ Component, state, url }) {
2323
? <meta property="og:image" content={state.ogImage} />
2424
: null}
2525
{state.noIndex ? <meta name="robots" content="noindex" /> : null}
26+
<meta name="color-scheme" content="light dark" />
2627
<link
2728
rel="preload"
2829
href={asset("/fonts/FixelVariable.woff2")}
@@ -42,8 +43,17 @@ export default define.page(function App({ Component, state, url }) {
4243
</>
4344
)
4445
: null}
45-
<script src="/theme.client.js"></script>
46-
<script type="module" src="/theme-toggle.client.js"></script>
46+
<script
47+
type="module"
48+
dangerouslySetInnerHTML={{
49+
__html: `
50+
const isDarkMode = localStorage.theme === "dark"
51+
|| (!("theme" in localStorage)
52+
&& window.matchMedia("(prefers-color-scheme: dark)").matches);
53+
document.documentElement.dataset.theme = isDarkMode ? "dark" : "light";`,
54+
}}
55+
>
56+
</script>
4757
</head>
4858
<body>
4959
<Component />

www/static/styles.css

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
@tailwind utilities;
44

55
/* Light and dark theme variables */
6-
.light {
6+
:root {
77
--fresh: 50deg, 100%, 56%;
88
--fresh-green: 142deg, 71%, 29%;
99

@@ -17,7 +17,7 @@
1717

1818
--info: 194deg, 76%, 41%;
1919
}
20-
.dark {
20+
html[data-theme="dark"]:root {
2121
--fresh: 50deg, 100%, 56%;
2222
--fresh-green: 142deg, 71%, 29%;
2323

@@ -104,3 +104,11 @@ hr {
104104
.dark-mode-toggle-button img {
105105
@apply fill-foreground-primary;
106106
}
107+
108+
::selection {
109+
background-color: #b1d5ff;
110+
}
111+
112+
html[data-theme="dark"] ::selection {
113+
background-color: #064c9c;
114+
}

0 commit comments

Comments
 (0)