Dark Mode Toggle and prefers-color-scheme
WARNING! This demo is using @container style() and :has to update preferred color-scheme. Only in latest Chrome.
HTML
<h1>Hello Darkness, My Old Friend</h1> <p><strong>WARNING!</strong> This demo is using <code>@container style()</code> and <code>:has</code> to update preferred color-scheme. <br>Only in latest Chrome.</p> <fieldset class="toggle-group" id="colorScheme"> <label> <input type="radio" name="color-scheme" id="color-scheme-light" value="0" data-sr> Light </label> <label> <input type="radio" name="color-scheme" value="auto" checked data-sr> Auto </label> <label> <input type="radio" name="color-scheme" id="color-scheme-dark" value="1" data-sr> Dark </label> </fieldset>
CSS
:where(html) {
--darkmode: 0;
container-name: root;
container-type: normal;
}
body {
--background-color: #fff;
--text-color: #222;
background-color: var(--background-color);
color: var(--text-color);
color-scheme: light dark;
font-family: ui-sans-serif, system-ui, sans-serif;
}
@media (prefers-color-scheme: dark) {
html {
--darkmode: 1;
}
}
@media (prefers-color-scheme: light) {
html {
--darkmode: 0;
}
}
html:has(#color-scheme-light:checked) {
--darkmode: 0;
}
html:has(#color-scheme-dark:checked) {
--darkmode: 1;
}
@container root style(--darkmode: 1) {
body {
--background-color: hsl(228, 5%, 15%);
--text-color: hsl(228, 5%, 80%);
}
}
/* DEMO */
.toggle-group {
border: 2px solid #ccc;
border-radius: 24px;
inline-size: fit-content;
padding: 3px;
}
.toggle-group label {
border-radius: 21px;
cursor: pointer;
display: inline-flex;
padding: 0.5em 1em;
text-align: center;
user-select: none;
}
.toggle-group label:has(input:checked) {
background-color: #ccc;
color: #333;
}
[data-sr] {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}