Why Your Figma Accessibility Annotations Aren't Reaching Developers
You annotated the file. You used the accessibility plugin, added the ARIA labels, left a note in the component description. Three weeks later the developer shipped it without any of it. When you asked, they said they didn't see it. That is the entire problem, and it's not the one most people think it is.
The annotations failed before a developer ever opened them. Not because developers don't care about accessibility, not because the spec was wrong, but because the way most Figma handoffs work, the notes were invisible by default.
Here are three places the signal gets lost, and what to do about each.
Annotations that exist but aren't seen
Most developers open your Figma file in Dev Mode. Dev Mode is a read-only view designed for extracting measurements, colours, and tokens, not for reading annotation layers. Plugin-based accessibility kits (Figma's built-in A11y Annotation Kit, Stark, and similar tools) create overlay layers that are visible in design mode but invisible or buried in Dev Mode by default. The developer who "didn't see it" was using the file exactly as most developers use Figma files.
The fix is boring: tell them to look. Add a comment directly in Dev Mode, which supports comments and is always visible. Or put a sticky note on the frame in a layer that renders in both views. If you use a plugin kit, add a text element at the top of the page that says: "Accessibility annotations are on the Annotations layer. Toggle it on in the layers panel before reviewing." Assume no developer will think to look for a layer they've never been told about. Because they won't.
Annotations that exist but can't be acted on
"Make this accessible" is not a spec. "Add ARIA" is not a spec. "Refer to WCAG" is really not a spec.
These tell the developer that accessibility matters to you. They don't tell them what to build. A developer reading "add ARIA" has to decide which roles, which properties, which states, and they'll make reasonable-sounding guesses that may be entirely wrong.
Every annotation should be actionable without additional research. Not "add a label to this icon button" but role: button, aria-label: "Close dialog". Not "this is a modal" but role: dialog, aria-labelledby: [modal-title-id], focus trap required, closes on Escape. If writing that out feels excessive, consider that the developer will spend more time making the wrong call and untangling it in QA than you spent writing the precise spec.
Annotations that exist but live in the wrong place
Component libraries create annotation problems. When a button has twelve variants across sizes, states, and themes, where does the annotation live? Usually on the default variant. Which means it doesn't apply to the disabled state, the icon-only version, or the loading state that needed annotations most.
The discipline: annotate at the variant level for anything that changes accessibility behaviour. A disabled button uses aria-disabled="true", not the HTML disabled attribute (that distinction matters for focus behaviour). A loading button might need aria-busy="true" and a visually hidden status message. If that's only annotated on the default variant, it gets missed when the developer implements the variant that actually has it.
What the annotation needs to say
When you annotate a component for a developer, four things need to be there: role, name, state, and relationship.
Role is what the element is. Button, dialog, listbox, tab, checkbox. If it's a custom component that mimics something standard, the role is especially important because the developer won't be using the standard HTML element.
Name is what assistive technology announces when it reaches the element. For icon-only buttons, this is the most common annotation failure. "Close" is the name. "X icon" is not.
State covers what changes about the element when it's interacted with: checked or unchecked, expanded or collapsed, selected, busy, disabled. Note whether disabled uses disabled or aria-disabled, because that distinction affects whether the element can receive focus.
Relationship covers what other elements this element controls or is controlled by. A button that opens a dropdown needs aria-controls. A tab that reveals a panel needs aria-controls pointing to that panel. A form field that has an associated error message needs aria-describedby pointing to it. If you're working through which roles to use in the first place, the ARIA roles guide for product designers covers that ground.
When to annotate and when to skip
Not every element needs an annotation. Annotation fatigue is real, and if your Figma file looks like it was attacked by a sticker kit, developers start treating the notes as background noise.
Custom interactive components always need annotations: anything built from scratch that mimics a standard UI pattern (custom dropdowns, date pickers, tab sets built from divs). Complex keyboard interactions always need annotations: anything with arrow key navigation, focus trapping, or roving tabindex. Icon-only controls always need annotations, every single one, without exception.
Standard HTML elements used correctly can usually be skipped. A <button> that says "Submit" needs no annotation. A standard navigation link to another page needs no annotation. The semantic HTML is already saying what needs to be said.
Forms sit in the middle. Annotate if labels aren't self-evident from surrounding context, or if there are validation states that appear dynamically. Status messages that appear without a page reload need annotations. Simple display text doesn't.
The test: if a developer implemented this with the obvious semantic HTML and nothing else, would it be accessible? If yes, skip the annotation. If no, write it.
Before you hand off
For each annotated component, check:
- Role specified explicitly (not implied by visual appearance)
- Accessible name provided (the announced name, not the visual label)
- State changes documented for each interactive state
- Keyboard behaviour described if it's non-standard
- Focus order noted if it differs from visual order
- Any
aria-controlsoraria-labelledbyrelationships mapped to specific IDs - A note visible in both design mode and Dev Mode pointing to the annotations layer
The annotation is a communication tool. When it's precise enough that a developer can implement it without guessing, it's done its job. Most of the time that means being more specific than feels necessary, writing exact attribute values rather than describing what you'd like to happen, and making sure the notes exist in a layer that developers can actually find. Getting the annotations right is only part of it.