{
    "componentChunkName": "component---src-templates-post-js",
    "path": "/pensieve/dark-mode-toggle",
    "result": {"data":{"markdownRemark":{"html":"<p>Dark mode toggle without the flash of default theme. Important bits:</p>\n<ul>\n<li>CSS variables for color theming</li>\n<li>Put <code class=\"language-text\">data-theme</code> attribute on <code class=\"language-text\">&lt;html></code>, not <code class=\"language-text\">&lt;body></code>, so we can run the JS before the DOM finishes rendering</li>\n<li>Run local storage check in the <code class=\"language-text\">&lt;head></code></li>\n<li>JS for toggle button click handler can come after render</li>\n</ul>\n<h2>HTML</h2>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\"><span class=\"token doctype\"><span class=\"token punctuation\">&lt;!</span><span class=\"token doctype-tag\">DOCTYPE</span> <span class=\"token name\">html</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>html</span> <span class=\"token attr-name\">lang</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>en<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">data-theme</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>light<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>head</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>meta</span> <span class=\"token attr-name\">charset</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>utf-8<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>meta</span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>viewport<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">content</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>width=device-width, initial-scale=1.0<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n    ...\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>script</span><span class=\"token punctuation\">></span></span><span class=\"token script\"><span class=\"token language-javascript\">\n      <span class=\"token comment\">// If there's a theme stored in localStorage, use it on the &lt;html></span>\n      <span class=\"token keyword\">const</span> localStorageTheme <span class=\"token operator\">=</span> localStorage<span class=\"token punctuation\">.</span><span class=\"token function\">getItem</span><span class=\"token punctuation\">(</span><span class=\"token string\">'theme'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>localStorageTheme<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        document<span class=\"token punctuation\">.</span>documentElement<span class=\"token punctuation\">.</span><span class=\"token function\">setAttribute</span><span class=\"token punctuation\">(</span><span class=\"token string\">'data-theme'</span><span class=\"token punctuation\">,</span> localStorageTheme<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span>\n    </span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>script</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>head</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>body</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>theme-toggle<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>button</span>\n        <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>theme-toggle-btn js-theme-toggle<span class=\"token punctuation\">\"</span></span>\n        <span class=\"token attr-name\">aria-label</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>Activate dark mode<span class=\"token punctuation\">\"</span></span>\n        <span class=\"token attr-name\">title</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>Activate dark mode<span class=\"token punctuation\">\"</span></span>\n      <span class=\"token punctuation\">></span></span>\n        <span class=\"token comment\">&lt;!--\n        &lt;svg class=\"light-mode\">\n          &lt;use xlink:href=\"#sun\">&lt;/use>\n        &lt;/svg>\n        &lt;svg class=\"dark-mode\">\n          &lt;use xlink:href=\"#moon\">&lt;/use>\n        &lt;/svg>\n        --></span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>button</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\n\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>script</span> <span class=\"token attr-name\">src</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>app.js<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token script\"></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>script</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>body</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>html</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<h2>CSS Variables</h2>\n<div class=\"gatsby-highlight\" data-language=\"css\"><pre class=\"language-css\"><code class=\"language-css\"><span class=\"token selector\">:root</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token property\">--bg</span><span class=\"token punctuation\">:</span> #ffffff<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">--text</span><span class=\"token punctuation\">:</span> #000000<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token selector\">[data-theme='dark']</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token property\">--bg</span><span class=\"token punctuation\">:</span> #000000<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">--text</span><span class=\"token punctuation\">:</span> #ffffff<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h2>JavaScript</h2>\n<div class=\"gatsby-code-title\">app.js</div>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> themeToggleBtn <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">querySelector</span><span class=\"token punctuation\">(</span><span class=\"token string\">'.js-theme-toggle'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nthemeToggleBtn<span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">'click'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">onToggleClick</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">const</span> <span class=\"token function-variable function\">onToggleClick</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> theme <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span>documentElement<span class=\"token punctuation\">.</span>dataset<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">const</span> themeTo <span class=\"token operator\">=</span> theme <span class=\"token operator\">&amp;&amp;</span> theme <span class=\"token operator\">===</span> <span class=\"token string\">'light'</span> <span class=\"token operator\">?</span> <span class=\"token string\">'dark'</span> <span class=\"token operator\">:</span> <span class=\"token string\">'light'</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">const</span> label <span class=\"token operator\">=</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">Activate </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>theme<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\"> mode</span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">;</span>\n\n  document<span class=\"token punctuation\">.</span>documentElement<span class=\"token punctuation\">.</span><span class=\"token function\">setAttribute</span><span class=\"token punctuation\">(</span><span class=\"token string\">'data-theme'</span><span class=\"token punctuation\">,</span> themeTo<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  localStorage<span class=\"token punctuation\">.</span><span class=\"token function\">setItem</span><span class=\"token punctuation\">(</span><span class=\"token string\">'theme'</span><span class=\"token punctuation\">,</span> themeTo<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  themeToggleBtn<span class=\"token punctuation\">.</span><span class=\"token function\">setAttribute</span><span class=\"token punctuation\">(</span><span class=\"token string\">'aria-label'</span><span class=\"token punctuation\">,</span> label<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  themeToggleBtn<span class=\"token punctuation\">.</span><span class=\"token function\">setAttribute</span><span class=\"token punctuation\">(</span><span class=\"token string\">'title'</span><span class=\"token punctuation\">,</span> label<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h2>Resources</h2>\n<ul>\n<li><a href=\"https://css-tricks.com/a-complete-guide-to-dark-mode-on-the-web/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://css-tricks.com/a-complete-guide-to-dark-mode-on-the-web/</a></li>\n<li><a href=\"https://css-tricks.com/flash-of-inaccurate-color-theme-fart/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://css-tricks.com/flash-of-inaccurate-color-theme-fart/</a></li>\n<li><a href=\"https://mxb.dev/blog/color-theme-switcher/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://mxb.dev/blog/color-theme-switcher/</a></li>\n<li><a href=\"https://www.joshwcomeau.com/react/dark-mode/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://www.joshwcomeau.com/react/dark-mode/</a></li>\n<li><a href=\"https://web.dev/prefers-color-scheme/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://web.dev/prefers-color-scheme/</a></li>\n</ul>","frontmatter":{"title":"Dark Mode Toggle","description":"Dark mode without the flash of default theme","date":"2021-04-21T00:00:00.000Z","slug":"/pensieve/dark-mode-toggle","tags":["Theming","Dark Mode"]}}},"pageContext":{}},
    "staticQueryHashes": ["1994492073","2009693873","2031412112","3825832676"]}