Buttons & forms
Push button
Pure CSSPress it. The edge is a generated box-shadow stack that collapses on :active.
A real checkbox underneath: click, tap or press Space. The rocker tips on :checked.
Your edited version
<input type="checkbox"> holds the state, so keyboard, forms and screen readers all work.display: none, which would remove it from the tab order).input:checked + .rocker tips it from rotateX(-22deg) to rotateX(22deg).<label> makes the whole switch clickable with zero JavaScript.input:checked + siblingrotateX rockerlabel makes the whole thing clickable<label class="switch">
<input type="checkbox">
<span class="rocker"><b>I</b><b>O</b></span>
<em></em>
</label>
.switch {
display: grid;
justify-items: center;
gap: 22px;
perspective: 320px;
cursor: pointer;
}
/* hidden but still focusable */
.switch input {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
}
.rocker {
display: grid;
grid-template-rows: 1fr 1fr;
width: 90px;
height: 146px;
border-radius: 14px;
background: linear-gradient(#2b3050, #161a30);
border: 1px solid #4a5280;
color: #8d95b3;
font: 700 1.6rem system-ui;
text-align: center;
box-shadow: 0 0 0 9px #05060c, 0 0 0 10px #4a5280;
transform: rotateX(-22deg); /* OFF */
transition: transform 0.18s cubic-bezier(0.3, 1.6, 0.5, 1);
}
.rocker b { display: grid; place-items: center; }
input:checked + .rocker {
transform: rotateX(22deg); /* ON */
color: #2ee6d6;
}
input:focus-visible + .rocker {
outline: 2px solid #2ee6d6;
outline-offset: 14px;
}
/* status LED */
.switch em {
width: 14px;
height: 14px;
border-radius: 50%;
background: #3a3f5c;
transition: 0.2s;
}
input:checked ~ em {
background: #2ee6d6;
box-shadow: 0 0 14px #2ee6d6;
}
.d-switch {
display: grid;
justify-items: center;
gap: 18px;
perspective: 320px;
cursor: pointer;
&__rocker {
display: grid;
grid-template-rows: 1fr 1fr;
width: 74px;
height: 120px;
border-radius: 12px;
background: linear-gradient(#2b3050, #161a30);
border: 1px solid var(--border-strong);
color: #8d95b3;
font-size: 22px;
text-align: center;
box-shadow:
0 0 0 8px #0b0d18,
0 0 0 9px var(--border-strong);
// OFF: bottom half pressed in
transform: rotateX(-22deg);
transition: transform 0.18s cubic-bezier(0.3, 1.6, 0.5, 1);
b {
display: grid;
place-items: center;
}
}
// status LED
em {
width: 12px;
height: 12px;
border-radius: 50%;
background: #3a3f5c;
transition: 0.2s;
}
// ON: top half pressed in
input:checked + &__rocker {
transform: rotateX(22deg);
color: var(--accent-2);
}
input:checked ~ em {
background: var(--accent-2);
box-shadow: 0 0 14px var(--accent-2);
}
input:focus-visible + &__rocker {
outline: 2px solid var(--accent-2);
outline-offset: 12px;
}
}