← back to Dw Theme Toggle
snippets/theme-toggle.liquid
98 lines
{%- comment -%}
DW Theme Toggle — sun/moon button in upper-right corner of every page.
Drop this snippet into theme.liquid, just inside <head>:
{% render 'theme-toggle' %}
Self-contained — no other edits required.
{%- endcomment -%}
<script>
/* Anti-flash: set data-theme on <html> before paint so the page never flashes the wrong theme on reload. */
(function () {
try {
var saved = localStorage.getItem('dw-theme');
if (!saved) {
saved = (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) ? 'light' : 'dark';
}
document.documentElement.setAttribute('data-theme', saved);
} catch (e) {
document.documentElement.setAttribute('data-theme', 'dark');
}
})();
</script>
<style>
/* Toggle button — upper-right of viewport, sticky so it floats over the header on every page. */
.dw-theme-toggle {
position: fixed; top: 14px; right: 16px;
width: 38px; height: 38px; border-radius: 50%;
background: rgba(0,0,0,0.45); color: #fff;
border: 1px solid rgba(255,255,255,0.22);
cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
font-size: 16px; line-height: 1; padding: 0;
transition: background 200ms, transform 200ms, color 200ms, border-color 200ms;
backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
z-index: 99999;
}
.dw-theme-toggle:hover { background: rgba(0,0,0,0.65); transform: scale(1.06); }
.dw-theme-toggle:focus-visible { outline: 2px solid #DDAB1E; outline-offset: 2px; }
.dw-theme-toggle .dw-icon-sun { display: none; }
.dw-theme-toggle .dw-icon-moon { display: inline; }
/* LIGHT theme — invert page colors but double-invert images/video so they stay correct.
This works on any Shopify theme without needing to know the theme's specific CSS vars. */
html[data-theme="light"] body {
filter: invert(1) hue-rotate(180deg);
background: #f5f1e8;
}
html[data-theme="light"] img,
html[data-theme="light"] video,
html[data-theme="light"] picture,
html[data-theme="light"] svg,
html[data-theme="light"] iframe,
html[data-theme="light"] [style*="background-image"],
html[data-theme="light"] .product-card img,
html[data-theme="light"] .product__media,
html[data-theme="light"] .media,
html[data-theme="light"] .image-bg,
html[data-theme="light"] .dw-theme-toggle {
filter: invert(1) hue-rotate(180deg);
}
html[data-theme="light"] .dw-theme-toggle {
background: rgba(255,255,255,0.55); color: #0a0a0a; border-color: rgba(0,0,0,0.18);
}
html[data-theme="light"] .dw-theme-toggle:hover { background: rgba(255,255,255,0.78); }
html[data-theme="light"] .dw-theme-toggle .dw-icon-sun { display: inline; }
html[data-theme="light"] .dw-theme-toggle .dw-icon-moon { display: none; }
/* Mobile sizing */
@media (max-width: 600px) {
.dw-theme-toggle { top: 10px; right: 12px; width: 34px; height: 34px; font-size: 14px; }
}
</style>
<script>
/* Inject the toggle button as soon as DOM is ready, then wire the click handler. */
(function () {
function build() {
if (document.getElementById('dw-theme-toggle')) return;
var btn = document.createElement('button');
btn.id = 'dw-theme-toggle';
btn.type = 'button';
btn.className = 'dw-theme-toggle';
btn.setAttribute('aria-label', 'Toggle dark/light theme');
btn.title = 'Toggle theme';
btn.innerHTML = '<span class="dw-icon-moon" aria-hidden="true">🌙</span><span class="dw-icon-sun" aria-hidden="true">☀️</span>';
btn.addEventListener('click', function () {
var cur = document.documentElement.getAttribute('data-theme') || 'dark';
var next = cur === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', next);
try { localStorage.setItem('dw-theme', next); } catch (e) {}
btn.setAttribute('aria-label', 'Switch to ' + (next === 'dark' ? 'light' : 'dark') + ' theme');
});
document.body.appendChild(btn);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', build);
} else {
build();
}
})();
</script>