20 Pure CSS Toggles & Switches
Skeuomorphic Light Switch
A physical rocker light switch — brushed metal bezel, plastic rocker that tilts on toggle, subtle shadow that deepens when pressed. Heavy realism, satisfying click.
Skeuomorphic Light Switch the 9th 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-skeo">
<input class="tg-skeo-input" type="checkbox" checked>
<span class="tg-skeo-bezel" aria-hidden="true">
<span class="tg-skeo-rocker">
<span class="tg-skeo-mark"></span>
</span>
</span>
<span class="tg-skeo-label">Power</span>
</label> .tg-skeo {
display: inline-flex;
align-items: center;
gap: 14px;
cursor: pointer;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 13px;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
color: #d8d4dc;
user-select: none;
}
.tg-skeo-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-skeo-bezel {
position: relative;
width: 56px;
height: 44px;
background: linear-gradient(180deg, #4a4a52 0%, #2a2a30 100%);
border-radius: 6px;
padding: 4px;
box-shadow:
inset 0 1px 1px rgba(255,255,255,0.18),
inset 0 -1px 1px rgba(0,0,0,0.5),
0 2px 4px rgba(0,0,0,0.3);
display: flex;
align-items: center;
justify-content: center;
}
.tg-skeo-rocker {
position: relative;
width: 100%;
height: 100%;
background: linear-gradient(180deg, #f4f1ec 0%, #d8d2c6 100%);
border-radius: 3px;
box-shadow:
inset 0 1px 0 rgba(255,255,255,0.8),
inset 0 -1px 0 rgba(0,0,0,0.15);
transition: transform 0.18s cubic-bezier(0.4, 0, 0.2, 1),
box-shadow 0.18s ease;
transform-origin: center;
}
.tg-skeo-mark {
position: absolute;
top: 6px; left: 50%;
width: 14px; height: 3px;
background: #2a2a30;
border-radius: 2px;
transform: translateX(-50%);
transition: top 0.18s ease, bottom 0.18s ease;
}
.tg-skeo-input:checked ~ .tg-skeo-bezel .tg-skeo-rocker {
transform: rotateX(0deg);
box-shadow:
inset 0 -1px 0 rgba(255,255,255,0.8),
inset 0 1px 0 rgba(0,0,0,0.15);
}
.tg-skeo-input:checked ~ .tg-skeo-bezel .tg-skeo-mark {
top: auto;
bottom: 6px;
background: #d04f4f;
}
.tg-skeo-input:not(:checked) ~ .tg-skeo-bezel .tg-skeo-rocker {
transform: rotateX(180deg);
}
.tg-skeo-input:focus-visible ~ .tg-skeo-bezel {
outline: 2px solid #6b9eff;
outline-offset: 4px;
}
@media (prefers-reduced-motion: reduce) {
.tg-skeo-rocker,
.tg-skeo-mark { transition: none; }
}