Checkbox (Single)

Checkbox (Single)

Whenever possible, you should use native HTML checkboxes, but it is possible to create ARIA checkboxes that act exactly like native checkboxes, for both sighted users and screen reader users, as this pattern shows.



Turn on a screen reader to experience this example in action.

Choose the ingredients for your pizza

  • Cheese
  • Mushrooms
  • Olives
  • Chicken

HTML Source Code

<h2 id="id-group-label">
    Choose the ingredients for your pizza
</h2>
<div role="group" aria-labelledby="id-group-label">
    <ul class="checkboxes">
      <li>
        <div role="checkbox"
             aria-checked="false"
             tabindex="0">
          Cheese
        </div>
      </li>
      <li>
        <div role="checkbox"
             aria-checked="true"
             tabindex="0">
          Mushrooms
        </div>
      </li>
      <li>
        <div role="checkbox"
             aria-checked="false"
             tabindex="0">
          Olives
        </div>
      </li>
      <li>
        <div role="checkbox"
             aria-checked="false"
             tabindex="0">
            Chicken
        </div>
      </li>
    </ul>
    
</div>
<!---
This component has been adapted from an example provided by the W3C, in accordance with the W3C Software and Document License https://www.w3.org/copyright/software-license-2023/
-->
  

JavaScript Source Code

class Checkbox {
    constructor(domNode) {
        this.domNode = domNode;
        this.domNode.tabIndex = 0;

        if (!this.domNode.getAttribute('aria-checked')) {
        this.domNode.setAttribute('aria-checked', 'false');
        }

        this.domNode.addEventListener('keydown', this.onKeydown.bind(this));
        this.domNode.addEventListener('keyup', this.onKeyup.bind(this));
        this.domNode.addEventListener('click', this.onClick.bind(this));
    }

    toggleCheckbox() {
        if (this.domNode.getAttribute('aria-checked') === 'true') {
        this.domNode.setAttribute('aria-checked', 'false');
        } else {
        this.domNode.setAttribute('aria-checked', 'true');
        }
    }

    /* EVENT HANDLERS */

    // Make sure to prevent page scrolling on space down
    onKeydown(event) {
        if (event.key === ' ') {
        event.preventDefault();
        }
    }

    onKeyup(event) {
        var flag = false;

        switch (event.key) {
        case ' ':
            this.toggleCheckbox();
            flag = true;
            break;

        
        default:
            break;
        }
        if (flag) {
        event.stopPropagation();
        }
    }

    onClick() {
        this.toggleCheckbox();
    }
}

// Initialize checkboxes on the page
window.addEventListener('load', function () {
let checkboxes = document.querySelectorAll('.checkboxes [role="checkbox"]');
for (let i = 0; i < checkboxes.length; i++) {
new Checkbox(checkboxes[i]);
}

});

//This component has been adapted from an example provided by the W3C, in accordance with the W3C Software and Document License https://www.w3.org/copyright/software-license-2023/

CSS Source Code

ul.checkboxes {
    list-style: none;
    margin: 0;
    padding: 0;
    padding-left: 1em;
  }
  
  ul.checkboxes li {
    list-style: none;
    margin: 1px;
    padding: 0;
  }
  
  [role="checkbox"] {
    display: inline-block;
    padding: 4px 8px;
    cursor: pointer;
  }
  
  [role="checkbox"]::before {
    position: relative;
    top: 1px;
    left: -4px;
    vertical-align: middle;
    content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='18' width='18' style='forced-color-adjust: auto;'%3E%3Crect x='1' y='1' height='15' width='15' rx='2' stroke='currentcolor' stroke-width='1' fill-opacity='0' /%3E%3C/svg%3E");
  }
  
  [role="checkbox"][aria-checked="true"]::before {
    position: relative;
    top: 1px;
    content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='18' width='18' style='forced-color-adjust: auto;'%3E%3Crect x='1' y='1' height='15' width='15' rx='2' stroke='currentcolor' stroke-width='1' fill-opacity='0' /%3E%3Cpolyline points='4,8 7,12 12,5' fill='none' stroke='currentcolor' stroke-width='2' /%3E%3C/svg%3E");
  }
  
  [role="checkbox"]:focus,
  [role="checkbox"]:hover {
    padding: 2px 6px;
    border: 2px solid #005a9c;
    border-radius: 5px;
    background-color: #def;
  }
  
  [role="checkbox"]:hover {
    cursor: pointer;
  }
  
  .checkbox-container {
      border: 2px solid #ded9d9;
      width: 20%;
      border-radius: 10px;
  }        
  /* Create a custom checkbox */
  .checkmark {
    /*
    position: absolute;
    top: 0;
    left: 0;
    */
    height: 20px;
    width: 20px;
    background-color: #eee;
    display: inline-block;
    vertical-align: middle;
  }
  
  /* On mouse-over, add a grey background color */
  .container:hover input ~ .checkmark {
    background-color: #ccc;
  }
  .checkmark:hover {
    background-color: #ccc;
  }
  
  /* When the checkbox is checked, add a blue background */
  .container input:checked ~ .checkmark {
    background-color: #2196F3;
  }
  
  /* Create the checkmark/indicator (hidden when not checked) */
  .checkmark:after {
    content: "";
    display: none;
  }
  
  /* Show the checkmark when checked */
  .container input:checked ~ .checkmark:after {
    display: block;
  }
  
  /* Style the checkmark/indicator */
   .checkmark[aria-checked="true"]:after {
    left: 9px;
    top: 5px;
    width: 5px;
    height: 10px;
    border: solid white;
    border-width: 0 3px 3px 0;
    -webkit-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
    transform: rotate(45deg);
  }
  /*
This component has been adapted from an example provided by the W3C, in accordance with the W3C Software and Document License https://www.w3.org/copyright/software-license-2023/
*/

Copy and Paste Full Page Example