DEV Community

Alex Carpenter
Alex Carpenter

Posted on • Originally published at alexcarpenter.me on

How to create custom checkbox and radio inputs with CSS

One major thing I forgot to outline in the screencast is ensuring there is a focused state applied to the custom indicator when the user has focused the input. The code provided below includes a focus state.

<!-- checkbox -->
<label class="control">
  <input type="checkbox" class="control__input visually-hidden">
  <span class="control__indicator"></span>
  Blue
</label>

<!-- radio -->
<label class="control">
  <input type="radio" name="color" class="control__input visually-hidden">
  <span class="control __indicator control__ indicator--radio"></span>
  Blue
</label>


.control {
  display: inline-flex;
  align-items: center;
}

.control__indicator {
  margin-right: .25rem;
  width: .75rem;
  height: .75rem;
  background-color: #ccc;
  border-radius: 3px;
}

.control__indicator--radio {
  border-radius: 50%;
}

.control __input:focus ~ .control__ indicator {
  box-shadow: 0 0 0 0.2rem rgba(38,143,255,.5);
}

.control __input:checked ~ .control__ indicator {
  background-color: #05f;
  background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij4gIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4gIDxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xOCA3bC0xLjQxLTEuNDEtNi4zNCA2LjM0IDEuNDEgMS40MUwxOCA3em00LjI0LTEuNDFMMTEuNjYgMTYuMTcgNy40OCAxMmwtMS40MSAxLjQxTDExLjY2IDE5bDEyLTEyLTEuNDItMS40MXpNLjQxIDEzLjQxTDYgMTlsMS40MS0xLjQxTDEuODMgMTIgLjQxIDEzLjQxeiIvPjwvc3ZnPg==');
  background-size: 80%;
  background-position: center;
  background-repeat: no-repeat;
}

/* Visually hide the browser input to ensure it is still focusable via keyboards */

.visually-hidden {
  border: 0;
  clip: rect(0 0 0 0);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  width: 1px;
}

Here's a demo on CodePen that you can play with.

Top comments (1)

Collapse
 
cydstumpel profile image
Cyd

Cool, i usually use the label to create the checkbox with before and after pseudo elements. If you place the label after the input you can select it with input:checked + label and style it accordingly 😄