Created
April 29, 2025 23:43
-
-
Save topdown/b4aaf47a3c19d173a9a08a1a8e3138ae to your computer and use it in GitHub Desktop.
Light / Dark mode
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en" class="light"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<title>Document</title> | |
<style> | |
:root { | |
--body-background: #fff; | |
color: #000; | |
} | |
html.dark { | |
--body-background: #000; | |
color: #fff; | |
} | |
html.dark #color_scheme_toggle { | |
background-color: #fff; | |
color: #000; | |
} | |
html.dark a .icon-sun { | |
color: #fff; | |
} | |
html.light #color_scheme_toggle { | |
background-color: #000; | |
color: #fff; | |
} | |
html.light a .icon-moon { | |
color: #000; | |
} | |
#color_scheme_toggle { | |
position: fixed; | |
bottom: 10px; | |
right: 10px; | |
background: none; | |
border: none; | |
cursor: pointer; | |
width: 32px; | |
height: 32px; | |
border-radius: 50%; | |
z-index: 9999; | |
text-align: center; | |
vertical-align: middle; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
padding: 4px; | |
} | |
.icon-sun, .icon-moon { | |
cursor: pointer; | |
transition: transform 0.3s ease; | |
} | |
body { | |
background-color: var(--body-background); | |
} | |
</style> | |
</head> | |
<body> | |
<main> | |
<h1>Test</h1> | |
<h2>Dark / Light mode</h2> | |
</main> | |
<a href="javascript:void(0)" id="color_scheme_toggle"> | |
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" | |
stroke-linecap="round" stroke-linejoin="round" class="icon-sun"> | |
<circle cx="12" cy="12" r="5" /> | |
<line x1="12" y1="1" x2="12" y2="3" /> | |
<line x1="12" y1="21" x2="12" y2="23" /> | |
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64" /> | |
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78" /> | |
<line x1="1" y1="12" x2="3" y2="12" /> | |
<line x1="21" y1="12" x2="23" y2="12" /> | |
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36" /> | |
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22" /> | |
</svg> | |
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" | |
stroke-linecap="round" stroke-linejoin="round" class="icon-moon"> | |
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" /> | |
</svg> | |
</a> | |
<script> | |
const CookieManager = { | |
set: (key, value, days = 365, path = '/') => { | |
const expires = new Date(Date.now() + days * 864e5).toUTCString(); | |
document.cookie = `${encodeURIComponent(key)}=${encodeURIComponent(value)}; expires=${expires}; path=${path}`; | |
}, | |
get: (key) => { | |
return document.cookie | |
.split('; ') | |
.find(row => row.startsWith(encodeURIComponent(key) + '=')) | |
?.split('=')[1] || null; | |
}, | |
delete: (key, path = '/') => { | |
document.cookie = `${encodeURIComponent(key)}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=${path}`; | |
} | |
}; | |
const html_tag = document.querySelector('html'); | |
const icon_sun = document.querySelector('.icon-sun'); | |
const icon_moon = document.querySelector('.icon-moon'); | |
// Remove existing theme classes | |
function setTheme(mode) { | |
html_tag.classList.remove('dark', 'light'); | |
html_tag.classList.add(mode); | |
if (mode === 'dark') { | |
icon_moon.style.display = 'block'; | |
icon_sun.style.display = 'none'; | |
} else { | |
icon_sun.style.display = 'block'; | |
icon_moon.style.display = 'none'; | |
} | |
} | |
// Get and apply theme | |
let theme = CookieManager.get('color_scheme'); | |
if (theme === 'dark' || theme === 'light') { | |
setTheme(theme); | |
} else { | |
// Fallback to browser preference | |
const prefers_dark = window.matchMedia('(prefers-color-scheme: dark)').matches; | |
theme = prefers_dark ? 'dark' : 'light'; | |
setTheme(theme); | |
CookieManager.set('color_scheme', theme); // Save it for next time | |
} | |
// Toggle theme | |
document.querySelector('#color_scheme_toggle').addEventListener('click', () => { | |
const current = html_tag.classList.contains('dark') ? 'dark' : 'light'; | |
const next = current === 'dark' ? 'light' : 'dark'; | |
setTheme(next); | |
CookieManager.set('color_scheme', next); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment