Feedback and affordances — making interactive things look interactive
An affordance is a visual cue that tells you what you can do with something — a button that looks pressable, a link that looks clickable. Feedback confirms what actually happened after you act. Interfaces that skip either leave users guessing, clicking blindly, or re-clicking out of doubt.
Intermediate
3 min read
Affordances: looking like what you can do
An affordance is a property of an object that suggests how it's used — a
door handle affords pulling, a flat push-plate affords pushing. In interfaces,
this means interactive elements should visually signal that they're
interactive: a button should look raised or bounded, a link should look
distinct from plain text (traditionally underlined or colored), a draggable
element should hint at its draggability.
The specific, common mistake: flat text that's secretly a button
A very common real interface bug: text styled identically to regular body
copy that is, in fact, a clickable action — nothing about its appearance
suggests it can be interacted with at all. Users don't hover over every word
on a page hoping to find hidden interactivity; if it looks like plain text, it
gets read like plain text and ignored as an action, regardless of what it
actually does when clicked.
States: hover, focus, active, disabled — each needs its own visual signal
An interactive element should visibly respond to each state a user can put it
in:
Hover — a subtle change (color shift, slight elevation) confirms "this
is interactive" before a click even happens
Focus — a visible outline or ring for keyboard users tabbing through the
page (covered in depth in the accessibility lesson ahead — this one is not
optional)
Active/pressed — a visual change the instant a click registers, giving
immediate confirmation the action was received
Disabled — visually distinct (commonly reduced opacity, a different
cursor) so it's clear an action isn't currently available, rather than just
silently doing nothing when clicked
Feedback: confirming what actually happened
Feedback is the other half of this lesson: after a user acts, the
interface should confirm what happened. A form submitted with no visible
response — no loading indicator, no success message, nothing — leaves a user
uncertain whether their click even registered, and a very common resulting
behavior is clicking again, sometimes triggering the action twice (directly
connecting to the idempotency concept from the Networking Fundamentals
domain's HTTP lesson — a UI that doesn't give feedback is exactly what
provokes the duplicate-click behavior that idempotent design has to defend
against).
Matching feedback to the action's actual outcome
Feedback should be honest about what happened — a generic "Success!" toast
shown regardless of outcome trains users to stop reading feedback messages at
all. A save that partially failed, a network error, a validation problem each
deserve their own specific, accurate message rather than a one-size-fits-all
confirmation that's sometimes simply wrong.
Immediate feedback for slow actions specifically
Anything that takes more than roughly 200-300ms should show some immediate
acknowledgment — a spinner, a disabled button state, a progress indicator —
even before the action fully completes. Without it, a user has no way to
distinguish "this is working" from "this is broken and did nothing," and the
natural response to uncertainty is usually to click again.