Skip to the page
TACTILE UI

Kit part · Checkboxes

Checklist

The kit’s check keys in nested groups. A group’s key is the sum of its items: all done, none, or some, and some is a key sunk halfway with a bar across it. The head counts the items, “3 of 7”, and its lamp lights when they are all done.

Element
<tui-checklist>
Needs
kit.css + kit.mjs
Rules
checklist.rules.md · 6
Finishes
Aluminium · Graphite · Porcelain · Black
Volumes
Tactile · Quiet
On this page
  1. Variants
  2. Every state, at once
  3. API
  4. Markup
  5. Accessibility
  6. How it’s built
  7. Rules
  8. Related parts
01

Variants

Some done

Some done

All done

All done · lamp lit

Not started

None done

Walk-round

Three levels

Unavailable

One item unavailable

Flat

Flat, no groups
02

Every state, at once

Both finishes, side by side. Hover, pressed and focus are forced with .is-hover, .is-down and .is-focus; checked and disabled are real.

Aluminium

PartNoneSomeAllFocusDisabled
Group key

Graphite

PartNoneSomeAllFocusDisabled
Group key
03

API

NameKindValuesWhat it does
<tui-checklist>elementnoneThe list. Works the groups out from their items, prints the counts and moves the keys.
.tui-checklist__headclasstitle · lamp · countThe head: a title, an optional lamp that lights when every item is done, and the counter.
output.tui-checklist__countelement“3 of 7”Counts items, not groups. A polite live region.
ul.tui-checklist__listclassnestedA list of items. Nest one in an item to make it a group.
li.tui-checklist__groupclassa groupAn item that holds a nested list. Its key has no name and no value: it is the sum of its items.
label.tui-checklist__row > input.tui-checkelementper itemA real checkbox in a label. Give an item a name and a value and a form posts it.
.tui-checklist__subclass“2 of 3”A group’s own count, written by script if you leave it out.
indeterminate · aria-checked="mixed"stateset by scriptA group with some items done: the key is sunk halfway with a bar across it. aria-checked mirrors it on every group.
data-completeattributeset by scriptOn the element while every item is done.
valuespropertyarray of stringsThe values of the ticked items.
tui-checklisteventdetail.done · total · valuesAfter a change. Bubbles. The checkboxes’ own change bubbles too.
checklistState · checklistPress · checklistCountfunctionkit.mjsThe rules, pure: a group’s state from its items’, what pressing a group does, and the words for the count.
↑ ↓ · Home · Endkeyboardon a keyMove between the keys. The list is one Tab stop.
→ · ←keyboardon a keyRight goes into a group; left goes back up to it.
Spacekeyboardon a keyPresses it.
04

Markup

<tui-checklist>
  <header class="tui-checklist__head">
    <h3 class="tui-checklist__title" id="pre-t">Before you fly</h3>
    <span class="tui-lamp"></span>
    <output class="tui-checklist__count" aria-live="polite"></output>
  </header>
  <ul class="tui-checklist__list" aria-labelledby="pre-t">
    <li class="tui-checklist__group">
      <label class="tui-checklist__row">
        <input class="tui-check" type="checkbox">
        <span class="tui-checklist__label">Cockpit</span>
        <span class="tui-checklist__sub"></span>
      </label>
      <ul class="tui-checklist__list">
        <li><label class="tui-checklist__row">
          <input class="tui-check" type="checkbox" name="check" value="fuel" checked>
          <span class="tui-checklist__label">Fuel</span>
        </label></li>
        …
      </ul>
    </li>
    <li><label class="tui-checklist__row">…Walk-round…</label></li>
  </ul>
</tui-checklist>
import '/kit/kit.mjs';   // defines <tui-checklist>

const list = document.querySelector('tui-checklist');
list.values;                                      // ['fuel', 'flaps', 'weather-brief']
list.addEventListener('tui-checklist', (e) => {
  e.detail.done;                                  // 3
  e.detail.total;                                 // 7: items, not groups
  e.detail.values;
});

// Items post under their own name; groups have none:
new FormData(form).getAll('check');

Needs kit.css and kit.mjs. How to install the kit.

05

Accessibility

  • Every item is a real checkbox in a label, so it is named, toggled by Space and posted by a form without any of this being reinvented.
  • A group with some items done is indeterminate, which the browser reports as mixed, and it carries aria-checked="mixed" as well; a screen reader says “mixed” where a sighted reader sees the half-sunk key.
  • The half-sunk key has a bar printed on it, so it reads without colour or depth in either finish. A finished item is struck through in ink, not faded.
  • The list is one Tab stop with the arrow keys inside it, so a long checklist is one press of Tab to pass; right and left arrows step into and out of a group.
  • The count, “3 of 7”, is a polite live region; the lamp beside it is only a second signal for “all done”.
  • Pressing a group that is already all done clears it. Pressing one with some done ticks them all: the same as any checkbox that is not ticked.
06

How it’s built

The check is the kit’s own: an 18px key that sinks when ticked, in a row 40px tall so a finger finds it. This part adds two things to it: a state between the two, drawn as the key sunk halfway with a 2px bar across it, and the logic that makes a group the sum of its items. checklistState is that sum, pure and tested, and the element runs it from the leaves up after every change, so groups nested three deep stay right. A pressed group writes its state down to everything under it. The roving Tab stop is the element’s too; the boxes are still native inputs, so a form, a label and a screen reader all behave as they do for a checkbox anywhere else.

07

Rules

checklist.rules.mdIn the brain

Steps in groups, where a group stands for what is under it and says so without colour.

6 rules in this file, with the foundations they rest on and the anti-patterns that break them. Full rules ship in the brain with the Pass.

08

Check

An option in a form: a small square key that presses below the plate when chosen, with a tick printed on it.

  1. IntroPiano, room mics1:12
  2. LodeFull band4:05
  3. Night reelVocal and tape3:42

List

Rows in a rack: a mark, a title, a second line and a fact or a key at the end. Chosen rows sink into a recess with their check key latched; in a running order, a row lifts out of the rack on its skirt and slides past the others, from the keyboard or by its grip.

Tariff

Three rates a day.

Reserve

—

Accordion

Printed sections that open in place. Each head ends in a small square key printed +; open, the key latches below the plate and reads −.

Docs
Finish
Volume