figma guide
Interactive components in Figma: hover, pressed, and disabled states that survive handoff
Model hover, pressed, focus, and disabled UI in Figma using variants, component properties, and prototype triggers—without breaking dev handoff or prototype previews.
- Published
- Updated
- May 20, 2026
- Read time
- 5 min
- Level
- Intermediate
Quick answer
In Figma, interactive behavior is split across two layers: Variants + component properties describe which pixels exist, and Prototype triggers (such as While hovering and On click) describe when the prototype swaps between those pixels. For product work, model hover, pressed, focus, and disabled as explicit variant properties (or well-named variants) so engineers see every state in the spec—not only what animates in Present mode. If you need carousel-level complexity, pair this guide with creating interactive carousels in Figma; for broader prototyping mechanics, start from how to use Figma to create a prototype.
Prerequisites
- Comfortable with Auto Layout stacks (padding and gap behave differently per state). Refresh with Figma Auto Layout in practice: real patterns if stacks fight you when padding changes.
- A decision on whether hover is prototype-only or must also appear as static artboards for documentation—many teams need both.
1. Separate “visual state” from “data state”
Designers often cram everything into one variant matrix: Size × Theme × Hover × Disabled × Loading. That explodes combinatorially and guarantees someone publishes a hover-disabled-loading monster state.
Better pattern:
- Interaction state (default, hover, pressed, focus-visible) as one axis when it changes visuals.
- Enabled / disabled as a boolean component property when it mostly toggles opacity, cursor treatment, and label color—not the whole layout.
- Loading as its own variant or nested instance swap when spinners replace labels.
Verdict: if two states look identical in the layers panel, they should not be different variants.
2. Build hover and pressed with variants first
Naming that survives handoff
Use names engineers recognize: state=rest, state=hover, state=pressed, state=focus. Avoid state=blue unless you are painting cars.
Padding and border shifts
Hover treatments often add border width or shadow. If Auto Layout children jump when the border grows, prefer inner strokes, ring shadows, or reserved transparent borders so layout geometry stays stable.
Disabled is not “50% opacity and hope”
Accessible disabled controls still need contrast decisions and sometimes helper copy explaining why an action is blocked. Pair visual work with the tooling notes in best Figma plugins for accessibility before you ship a glassy disabled button nobody can read.
3. Add prototype wiring for demos (While hovering / On click)
Once variants exist, wire interactions in the Prototype panel:
- Select the interactive layer (usually the component instance root).
- Create a connection from
state=rest→state=hoverwith trigger While hovering (or On hover depending on your Figma build naming). - Add On click (or While pressing where available) from default to
state=pressed, then After delay back to default if you want a tactile “bounce.” - Use Smart animate only when layer IDs match across variants—rename layers consistently or animation will pop.
Common mistake: wiring hover on a child icon while the hit area is the parent frame—present mode will miss hovers on desktop web expectations. Keep the clickable region one logical layer.
For deeper trigger lists (drag, keys, overlays), the reference table in how to use Figma to create a prototype stays the canonical walkthrough.
4. Use boolean props for “pressed” toggles without doubling components
Toggles, segmented controls, and filter chips often need selected / unselected more than literal mouse-down pixels.
- Add a boolean like
isSelectedand bind style swaps (fills, borders, icon color) to that property. - Keep literal
pressedvariants for moments when shadow depth or scale changes matter for marketing prototypes.
Verdict: booleans keep the library smaller; reserved variants keep marketing demos shinier.
5. Focus-visible deserves a real state—even if you rarely present it
Keyboard users should see focus rings that are not identical to hover outlines. Give state=focus its own stroke or shadow token, and document when hover and focus may coincide (touch devices often skip hover).
If your team centralizes tokens, bind ring colors to semantic variables so dark mode does not invent a neon halo—Variables & modes explains the binding discipline.
6. Nested interactives: the rules of thumb
Figma prototypes do not behave like a browser event tree. When you nest interactive components:
- Expect hover conflicts if parent and child both try to own
While hovering. - Prefer one interactive root per control; use passive groups inside.
- For complex widgets (date pickers, comboboxes), ship annotated still frames plus a simplified prototype rather than pretending every submenu is production-faithful.
7. Handoff checklist your engineers will actually read
| Question | Pass |
|---|---|
| Does every button show default, hover, disabled, loading? | Screenshots or variants exist |
| Is focus-visible defined for keyboard flows? | Distinct from hover |
| Are hit targets at least ~44px where mobile applies? | Annotated frame or component note |
| Do tokens explain why disabled is disabled? | Spec text or companion doc |
| Are prototype wires optional extras, not the only spec? | Yes |
Developer-centric plugin options live in best Figma plugins for developers when you need inspect-ready extensions beyond vanilla Dev Mode.
8. Library governance so states do not rot
- Publish from a library file, not the day’s exploration page—how to organize a Figma file so it scales covers covers, pages, and naming.
- Add contribution rules: new variants require changelog text in the description field.
- When Figma ships UI changes, schedule a quarterly state audit—see Figma quarterly check-in: what to update for a refresh cadence template.
FAQ
Should every hover state also be a variant?
If hover only changes shadow and you can document it with a token note, sometimes a single variant + annotation is enough. If hover changes layout (reveals chips, expands menus), variants or separate frames reduce ambiguity.
Why does Smart Animate glitch between my hover variants?
Usually layer structure drift—rename children identically across variants or remove stray groups.
Can I prototype disabled buttons clicking through?
Do not rely on prototype realism for disabled—mark disabled instances in design specs explicitly; engineering should enforce guards in code.
Bottom line
Treat variants as the contract for what exists, prototype triggers as the movie trailer for what moves, and component properties as the lever product teams toggle without forking the library. Get that separation right, and hover or pressed work stays legible in both Present and handoff—which is the only definition of “interactive” that matters across the whole team.
For system-wide consistency beyond one button, continue into best Figma plugins for design systems and keep the Figma guides hub bookmarked for adjacent setup topics.
§ Keep reading