The button is a promise with states
A button has five states and each is a promise: rest (this will do something), hover (it knows you are here), active/pressed (it has heard you), focus (the keyboard can reach it), and disabled (it cannot — and here is the promise most products break). Users do not read documentation; they read states. A button whose states lie is a button that teaches users to distrust the whole product.
- Rest: the label is a verb that names the outcome — 'Save changes', never 'Submit'. 'OK' is what a dialog says when it has given up explaining.
- Hover: the change must be legible at a glance — background shift, slight lift — and must not be the only affordance on a touchscreen that has no hover.
- Pressed: instant visual response (scale to 0.97, fill change) inside 60ms. The press state is the product saying 'I heard you' before the network says anything.
- Focus: a visible ring that appears on keyboard focus and does not vanish on mouse click — and never, ever outline: none without a replacement.
- Disabled: here is the rule — if the button is disabled because the form is incomplete, say what is missing instead of disabling. Disable only when the action is genuinely impossible right now (already saving, nothing selected), and always explain why, next to the button, in text.
Semantics are the API
<button type="button"> <!-- click, no form submit -->
<button type="submit"> <!-- the form's action -->
<button disabled> <!-- genuinely unavailable -->
<a role="button" tabindex="0"> <!-- only if it navigates; else a <button> -->
<!-- A <div onClick> is a button that lost its keyboard,
its focus ring, its screen-reader role, and its dignity. -->A button with no type attribute inside a form defaults to type='submit'. The 'settings' button that submits the search form and navigates away is a debugging classic — declare type='button' on every button that is not the submitter, and your users will stop losing their work.
The craft details
A button's padding is its hit area: the tap target needs 44×44px even when the visual is smaller, via padding or an invisible hit-slot. Its corners should match the product's radius scale, not the nearest trend. Its label should never wrap mid-phrase ('Save all' is fine; 'Save all changes to the current draft and' is a sentence wearing a button's clothes). And when the action is destructive, the button says what it will do — 'Delete comment', with the confirm as a second step, never a surprise.