CSS Only Switch Style Checkboxes

Author: Jason Miller
Views Total: 576 views
Official Page: Go to website
Last Update: July 2, 2021
License: MIT


CSS Only Switch Style Checkboxes


Use plain HTML and CSS to create switch-style accessible checkboxes.

How to use it:

1. Add the role=”switch” attribute to checkboxes and wrap them into respective label elements as follows:

  <input type="checkbox" role="switch" disabled>
  <input type="checkbox" role="switch" checked>
  Disabled + Checked
  <input type="checkbox" role="switch" indeterminate>

2. The CSS styles to transform the checkboxes into switches.

input[role=switch] {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  display: inline-block;
  width: 2.4em;
  height: 1.4em;
  margin: -.2em 0;
  box-sizing: content-box;
  padding: 0;
  border: none;
  border-radius: .7em;
  background: rgba(160,160,160,0.7);
  box-shadow: 0 .15em .25em rgba(0,0,0,0.5) inset, 0 -.5px 0 rgba(255,255,255,0.2) inset;
  transition: background-color 250ms ease, box-shadow 250ms ease;
  font-size: 100%;
  text-size-adjust: 100%;
  -webkit-text-size-adjust: 100%;
  user-select: none;
  outline: none;
input[role=switch]::before {
  content: '';
  display: flex;
  align-content: center;
  justify-content: center;
  position: absolute;
  width: 1em;
  height: 1em;
  left: 0;
  top: 0;
  background: rgba(240,240,240,0.9);
  box-shadow: 0 1px 1px #fff inset, 0 .2em .5em rgba(255,255,255,0.7) inset, 0 -.2em .3em rgba(0,0,0,0.2) inset, 0 .05em .25em rgba(0,0,0,0.7);
  border-radius: 50%;
  transform: translate(20%, 20%);
  transition: transform 250ms ease;
  color: rgba(0,0,0,0.3);
  line-height: 1;
input[role=switch]:focus::before {
  background: rgba(255,255,255,0.9);
input[role=switch]:checked {
  background-color: var(--bg-checked, var(--bg, rgb(60,130,250)));
input[role=switch]:focus-visible {
  box-shadow: 0 .15em .25em rgba(0,0,0,0.5) inset, 0 -.5px 0 rgba(255,255,255,0.2) inset, 0 0 0 2px rgba(255,255,255,0.8), 0 0 0 4px var(--bg-checked, var(--bg, rgb(60,130,250)));
input[role=switch]:checked::before {
  transform: translate(120%, 20%);
input[role=switch]:indeterminate::before {
  transform: translate(70%, 20%);
  content: '-';
input[role=switch]:disabled:before {
  opacity: 0.4;
See also  Center The Html Element On The Screen with Pure CSS

Leave a Reply

Your email address will not be published. Required fields are marked *