One panel, five components
A notification settings panel — the ordinary screen every product has. It is also the clearest place to see the distinction this page is built on: the two switches at the top act the moment you move them, and everything below waits for Save.
Move a switch, then save the rest.Three checkboxes share one name, so the form receives
include three times — the same shape a native checkbox group submits, and the reason a server handler needs no special case for these.
A switch is not a checkbox with a different skin. A checkbox states an intention that a form will act on later, so it belongs beside a Save button and it can be indeterminate; a switch acts now, which is why it has no third state and why putting one inside a form that has to be submitted is the commonest way to make people wonder whether their change took.
Checkbox
The same chrome as the text fields, turned on its side: the caption sits beside the box rather than above it, and the help text lines up with the caption rather than with the tick.
The box you see is not the input. The real <input> fills a 24 × 24 pixel target invisibly and the tick is drawn inside it, so WCAG 2.2 SC 2.5.8 is met at every size and whether or not the caption is showing. Try clicking just outside the smallest box above.
Radio group
One answer from several. The group holds the value, the keyboard and the form participation; the options only render, which is what makes two of them selected at once impossible rather than merely unlikely.
A disabled option is stepped over rather than focused and ignored, and a group whose options are all disabled hands out no tab stop at all — exactly as a native group of disabled radios does.
Switch
For a setting that takes effect the moment it moves. A checkbox states an intention a form will act on later; a switch acts now — which is why it has no third state.
The thumb travels rather than jumping, because the travel is the feedback — a switch often has nothing else on screen to confirm it did anything. Under prefers-reduced-motion it arrives at once, which removes the animation without removing the confirmation.
Slider
A value along a track, or a range between two of them. The one form component that is not built on a native input — because there is no native two-ended slider, and shipping the two cases on different mechanisms would mean two keyboards in one tag.
role="slider" elements, not one with two values — so each thumb can be told how far it may go before it meets the other. The thumbs never cross.
A drag uses pointer capture, so it keeps working when the pointer leaves the track — past the end, out of the window, over an iframe — and releases itself if the pointer is lost. format supplies the value bubble, the tick labels and aria-valuetext together, so a price slider cannot show "£1,200" while announcing "1200".
Rating
The last of tier one, and the one that argues with itself: it reads like a small set of answers, which is a radio group, and it draws as a value along a scale, which is a slider. It takes the keyboard from one and the role from the other.
role="img" with the value as its accessible name, and it takes no tab stop. Showing an average beside a review is not a control, and publishing it as one puts a widget in the tab order that answers to nothing the user does.
icon-path takes your own in a 24×24 box.
aria-valuetext says "3 of 5 stars", because aria-valuenow="3" on a row of icons is a quantity with no unit and no scale attached to it. Each icon is one shape painted twice — the empty glyph with a filled copy over it, clipped by inline-size — so a half never shimmers along its seam, a right-to-left row fills from the correct edge with no second rule, and a fill of 30% would need nothing added. And zero submits nothing at all rather than score=0: a form cannot otherwise tell "rated nought" from "not rated".