Interaction states
Also called button states or UI states
The set of looks a control takes as people use it, such as default, hover, pressed, focused, and disabled, each showing what will happen.
const BUTTON = [
'rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white transition-[background-color,scale] duration-150',
// Hover: Tailwind 4 applies hover: only on devices that can hover.
'enabled:hover:bg-blue-700',
// Pressed
'enabled:active:scale-[0.97]',
// Keyboard focus, without a ring on mouse clicks
'focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-blue-600',
// Disabled; enabled: above keeps hover and press effects off it
'disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground'
].join(' ');
export function PublishActions({ canPublish }: { canPublish: boolean }) {
return (
<div className='flex gap-3'>
<button type='button' className={BUTTON}>
Save draft
</button>
<button type='button' disabled={!canPublish} className={BUTTON}>
Publish
</button>
</div>
);
}Give every button in the app five clear states: default, hover (background one step darker with a 150ms transition), pressed (scale to 0.97), keyboard focus (a 2px outline with a 3px offset using :focus-visible, so mouse clicks don’t show it), and disabled (gray background, muted text, cursor: not-allowed, no hover effect). Apply hover styles only on devices that support hover.
Paste into Layerwise or any AI coding tool.
What is Interaction states?
Every interactive element has states. A button rests in its default look, darkens a little on hover, shrinks or darkens further while pressed (:active), shows a ring when reached with the keyboard (:focus-visible), and fades when it can’t be used (:disabled). Each state answers a question: can I click this, did my click land, where am I?
Design all five whenever you add a button, link, input, or menu item. Missing states make an app feel broken: a button with no pressed state feels unresponsive, and one with no focus state is unusable for keyboard users.
Keep the changes small and quick: a background one step darker on hover, a 2–4% shrink on press, transitions around 150ms. Touch screens have no hover, so never hide anything essential behind it. Also note that :hover still matches a disabled button, so scope hover styles with :hover:not(:disabled).
Often confused with
- Button variants
- Button variants are different styles of button, such as primary, secondary, and ghost. Interaction states are how one button changes while someone uses it.
Related terms
All termsHover effect
A visual change, such as a lift, glow, or zoom, that happens when the mouse pointer moves over an element to show it can be clicked.
Press feedback
A quick visual response, usually a slight shrink, that shows a button registered the press the moment a finger or mouse button goes down.
Focus ring
An outline that marks which element has keyboard focus, so people moving through a page with the Tab key can see where they are.
Button variants
A set of button styles, such as primary, secondary, outline, ghost, destructive, and link, that shows which action on a screen matters most.
Build it with Layerwise
Describe your app, watch it run in a live preview, and publish it with a database, storage, and sign-in built in.