20 Pure CSS Toggles & Switches
Day / Night
A dark-mode toggle that morphs from a sun in a sky-blue track to a crescent moon over a deep night track. The most "what does this control" pattern in the bunch.
Day / Night the 12th of 20 designs in the 20 Pure CSS Toggles & Switches collection. The design is implemented in pure CSS — no JavaScript required. Copy the HTML and CSS panels below into your project. Because the demo is pure CSS, it works in any framework or templating engine you happen to use. The design honours prefers-reduced-motion and uses real semantic markup, so it ships accessibility-ready out of the box.
Live preview
The code
<label class="tg-dn" aria-label="Theme: light or dark">
<input class="tg-dn-input" type="checkbox" checked>
<span class="tg-dn-track" aria-hidden="true">
<span class="tg-dn-thumb">
<span class="tg-dn-crater tg-dn-c1"></span>
<span class="tg-dn-crater tg-dn-c2"></span>
<span class="tg-dn-crater tg-dn-c3"></span>
</span>
<span class="tg-dn-star tg-dn-s1"></span>
<span class="tg-dn-star tg-dn-s2"></span>
<span class="tg-dn-star tg-dn-s3"></span>
</span>
</label> .tg-dn {
display: inline-flex;
cursor: pointer;
user-select: none;
}
.tg-dn-input {
position: absolute;
width: 1px; height: 1px;
padding: 0; margin: -1px;
overflow: hidden; clip: rect(0,0,0,0);
white-space: nowrap; border: 0;
}
.tg-dn-track {
position: relative;
width: 72px;
height: 36px;
background: linear-gradient(180deg, #87ceeb 0%, #4a90c2 100%);
border-radius: 999px;
overflow: hidden;
transition: background 0.4s ease;
box-shadow: inset 0 1px 3px rgba(0,0,0,0.2);
}
.tg-dn-thumb {
position: absolute;
top: 3px;
left: 3px;
width: 30px; height: 30px;
border-radius: 50%;
background: radial-gradient(circle at 35% 35%, #ffe066 0%, #f5a623 90%);
box-shadow: 0 0 14px rgba(255, 224, 102, 0.7);
transition: left 0.4s cubic-bezier(0.4, 0, 0.2, 1),
background 0.4s ease,
box-shadow 0.4s ease;
}
.tg-dn-crater {
position: absolute;
border-radius: 50%;
background: #2a2a30;
opacity: 0;
transition: opacity 0.4s ease;
}
.tg-dn-c1 { top: 6px; left: 8px; width: 6px; height: 6px; }
.tg-dn-c2 { top: 14px; left: 18px; width: 4px; height: 4px; }
.tg-dn-c3 { top: 20px; left: 6px; width: 5px; height: 5px; }
.tg-dn-star {
position: absolute;
width: 2px; height: 2px;
background: #fff;
border-radius: 50%;
opacity: 0;
transition: opacity 0.4s ease;
}
.tg-dn-s1 { top: 8px; left: 14px; }
.tg-dn-s2 { top: 18px; left: 24px; width: 1.5px; height: 1.5px; }
.tg-dn-s3 { top: 10px; left: 28px; }
.tg-dn-input:not(:checked) ~ .tg-dn-track {
background: linear-gradient(180deg, #0a1322 0%, #1c2540 100%);
}
.tg-dn-input:not(:checked) ~ .tg-dn-track .tg-dn-thumb {
left: 39px;
background: radial-gradient(circle at 35% 35%, #e8e6f0 0%, #a8a5bb 90%);
box-shadow: 0 0 12px rgba(168, 165, 187, 0.5);
}
.tg-dn-input:not(:checked) ~ .tg-dn-track .tg-dn-crater { opacity: 0.5; }
.tg-dn-input:not(:checked) ~ .tg-dn-track .tg-dn-star { opacity: 0.85; }
.tg-dn-input:focus-visible ~ .tg-dn-track {
outline: 2px solid #ffe066;
outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
.tg-dn-track,
.tg-dn-thumb,
.tg-dn-crater,
.tg-dn-star { transition: none; }
}