Sobes.tech
Junior

How to style checkboxes using CSS without using libraries?

sobes.tech AI

Answer from AI

To style a checkbox without libraries, you can use a combination of hiding the standard element and styling pseudo-elements ::before or ::after associated with the parent <label>.

  • Hiding the standard checkbox:

    input[type="checkbox"] {
      display: none; /* or visibility: hidden; height: 0; width: 0; */
    }
    
  • Creating a styled "square" using the <label> pseudo-element:

    input[type="checkbox"] + label::before {
      content: ''; /* Required for displaying the pseudo-element */
      display: inline-block;
      width: 1em; /* Size of the square */
      height: 1em; /* Size of the square */
      border: 1px solid #ccc; /* Square border */
      margin-right: 0.5em; /* Spacing from label text */
      vertical-align: middle; /* Vertical alignment */
      /* Other styles as desired: background-color, border-radius, box-shadow */
    }
    
  • Style for the checked state:

    Use the checked selector for input and change the styles of the label pseudo-element accordingly.

    input[type="checkbox"]:checked + label::before {
      background-color: #007bff; /* Background color when checked */
      border-color: #007bff; /* Border color when checked */
      /* Other styles as desired */
    }
    
  • Adding a "check" mark (or another indicator):

    You can use a second pseudo-element (::after) or style the existing ::before with background-image (svg, data-url) or border styling.

    Example with border to create a check mark:

    input[type="checkbox"]:checked + label::after {
      content: '';
      display: inline-block;
      width: 0.4em; /* Width of the check mark line */
      height: 0.7em; /* Height of the check mark line */
      border-right: 2px solid white; /* Right part of the check mark */
      border-bottom: 2px solid white; /* Bottom part of the check mark */
      transform: rotate(45deg); /* Rotate to form the check mark */
      position: absolute; /* For positioning inside `::before` */
      top: 0.1em; /* Position adjustment */
      left: 0.3em; /* Position adjustment */
      /* The parent label::before may need `position: relative;` */
    }
    

For the last example to work correctly, add position: relative; to input[type="checkbox"] + label::before:

input[type="checkbox"] + label::before {
  /* ... previous styles ... */
  position: relative; /* Add for positioning `::after` */
}

This approach provides full control over the appearance of the checkbox and good accessibility, as the standard element still exists and responds to user actions (click, focus). It is important to link input with label using id and for attributes for proper operation when clicking on the label text.

<input type="checkbox" id="myCheckbox">
<label for="myCheckbox">Agree to terms</label>