checkbox

Checkboxes can have three states: checked, unchecked and indeterminate. The first two are reachable via normal click interactions, the indeterminate state can only be reached by using the DOM API. Look for the example below and the DOM API example at the end of this page.

See Form for example usage in a form.

In order for checkboxes to work correctly, the input tag needs a unique id attribute and the label tag needs the same for attribute.
If you want to use multiple checkboxes that are related to each other, we recommend to wrap those in a group. This will support the user experience and assistive tools like screen readers. Further explanation can be found here.

component variations

unselected checkbox

<div class="a-checkbox">
  <input type="checkbox" id="checkbox-1" name="unselected checkbox" />
  <label for="checkbox-1">Checkbox Label</label>
</div>

unselected checkbox disabled

<div class="a-checkbox">
  <input
    type="checkbox"
    id="checkbox-2"
    disabled=""
    name="unselected checkbox disabled"
  />
  <label for="checkbox-2">Checkbox Label</label>
</div>

selected checkbox

<div class="a-checkbox">
  <input type="checkbox" id="checkbox-3" name="selected checkbox" checked="" />
  <label for="checkbox-3">Checkbox Label</label>
</div>

multiline label checkbox

<div class="a-checkbox">
  <input
    type="checkbox"
    id="checkbox-multiline-label"
    name="multiline label checkbox"
    checked=""
  />
  <label for="checkbox-multiline-label">
    First line
    <br />
    Second line
  </label>
</div>

selected checkbox disabled

<div class="a-checkbox">
  <input
    type="checkbox"
    id="checkbox-5"
    disabled=""
    name="selected checkbox disabled"
    checked=""
  />
  <label for="checkbox-5">Checkbox Label</label>
</div>

indeterminate checkbox

An indeterminate checkbox is neither checked nor unchecked. This state is removed automatically after an interaction with the element. You can use the API to set or unset this state as well.

<div class="a-checkbox a-checkbox--indeterminate">
  <input type="checkbox" id="checkbox-6" name="indeterminate checkbox" />
  <label for="checkbox-6">Checkbox Label</label>
</div>

indeterminate checkbox disabled

<div class="a-checkbox a-checkbox--indeterminate">
  <input
    type="checkbox"
    id="checkbox-7"
    disabled=""
    name="indeterminate checkbox disabled"
  />
  <label for="checkbox-7">Checkbox Label</label>
</div>

additional content

demo

export default (): void => {
    const indeterminateCheckboxes = document.querySelectorAll('.a-checkbox.a-checkbox--indeterminate');

    [...indeterminateCheckboxes].forEach(checkbox => {
        if (checkbox.querySelector('input')) {
            checkbox.querySelector('input').indeterminate = true;
        }
    })
}```

styles SCSS

@mixin checkbox-icon {
  color: var(--major-accent__enabled__front__default);
  position: absolute;
  content: '';
  left: 0;
}

/* stylelint-disable selector-no-qualifying-type */
.a-checkbox {
  display: flex;
  position: relative;
  height: auto;

  label {
    color: var(--plain__enabled__front__default);
    background-color: var(--plain__enabled__fill__default);
    position: relative;
    left: 0;
    margin: 0;
    line-height: 1.5;
    font-size: 1rem;
    min-height: 1.5rem;
    padding-left: 2rem;
    display: flex;
    align-items: flex-start;

    &::before {
      position: absolute;
      top: 0;
      left: 0;
      background-color: var(--small__enabled__fill__default);
      content: '';
      display: inline-block;
      height: 1.5rem;
      width: 1.5rem;
    }
  }

  input[type='checkbox'] {
    width: 0;
    opacity: 0;
    height: 0;
    -moz-appearance: none;

    // Cursors Definitions
    &:hover ~ label,
    &:active ~ label {
      cursor: pointer;
    }

    &:disabled ~ label {
      cursor: default;
      color: var(--plain__disabled__front__default);
      background-color: var(--plain__disabled__fill__default);
    }

    // unselected state
    &:hover ~ label::before {
      background-color: var(--small__enabled__fill__hovered);
    }

    &:active ~ label::before {
      background-color: var(--small__enabled__fill__pressed);
    }

    &:disabled ~ label::before {
      background-color: var(--small__disabled__fill__default);
      pointer-events: none;
    }

    // Default Icon Rules
    &:checked ~ label::after {

      @include uiIconForComponents();
      @include checkbox-icon();

      content: var(--ui-ic-checkmark);
    }

    // selected state
    &:checked ~ label::before {
      background-color: var(--major-accent__enabled__fill__default);
    }

    &:checked:hover ~ label::before {
      background-color: var(--major-accent__enabled__fill__hovered);
    }

    &:checked:active ~ label::before {
      background-color: var(--major-accent__enabled__fill__pressed);
    }

    &:checked:disabled {
      ~ label::before {
        background-color: var(--major-accent__disabled__fill__default);
      }

      ~ label::after {
        color: var(--major-accent__disabled__front__default);
      }
    }

    // Outline for keyboard navigation
    &:focus-visible ~ label::before {
      outline: 3px solid var(--plain__enabled__front__default);
      outline-offset: 3px;
    }
    &:focus-visible ~ label::after {
      outline: 3px solid var(--background);
    }
  }

  /* stylelint-disable no-descending-specificity */
  &--indeterminate input[type='checkbox'],
  input[type='checkbox']:indeterminate {
    ~ label::after {

      @include uiIconForComponents();
      @include checkbox-icon();

      content: var(--ui-ic-indeterminate);
    }

    ~ label::before {
      background-color: var(--major-accent__enabled__fill__default);
    }

    &:hover ~ label::before {
      background-color: var(--major-accent__enabled__fill__hovered);
    }

    &:active ~ label::before {
      background-color: var(--major-accent__enabled__fill__pressed);
    }

    &:disabled {
      ~ label::before {
        background-color: var(--major-accent__disabled__fill__default);
      }

      ~ label::after {
        color: var(--major-accent__disabled__front__default);
      }
    }
  }
}