Annotating Mockups & Wireframes for Accessibility

Why annotate

The university is required to produce IT that everyone in our community can use equally. By “shifting left” and ensuring that we take accessibility into account at the design stage of web and app projects, we facilitate compliance at the development stage. This results in a process that is:

  1. Cheaper. It is less resource intensive to flag possible accessibility issues at the design stage. The alternative is having these issues crop up during development, or even worse, after development.

  2. More efficient. Developers will appreciate the specificity of the annotations and be able to produce the IT much faster.

  3. Educational. Accessibility is everyone’s job. UX practitioners should know that their designs have accessibility implications and what these are. Developers need to know how to produce accessible IT. Annotating designs bridges the gap between both. UX practitioners learn to specify how the design needs to be implemented to be accessible. In time, developers learn how to do so even in the absence of the annotations.

What to annotate

Though annotating designs is a very useful practice, there is a large percentage of the accessibility issues that cannot be annotated. Be sure developers know this and have them incorporate testing as they develop in order to catch issues that have not been accounted for.

Note: This document mentions “guidelines” - the guidelines currently in place are WCAG 2.1 and and U-M follows the AA standard.

Color and contrast

Structure and meaning

To the naked eye, the design pretty much lays out the structure of the view. But we are also required to offer this structure to someone who cannot see and who is using screen reader software to navigate and read the IT. There are two complementary methods of achieving this:


Follow proper heading structure. The view needs to have a visual title. Depending on the visual structure, other subtitles may be necessary. In your annotations the main title should be an <h1>, subsequent titles will be <h2>, <h3>....<h6>. There should be no heading jumps or gaps.
Solution: specify the heading levels in your design annotations.


Label the landmark regions of a view. Mentally slice and dice the view into semantic chunks by the intended function of the chunk. These could be something like branding, menu, footer, main content, sidebar, subsection, etc. All of these can be expressed semantically in the markup and it is your charge to help the developer to do so. These are the annotations they will need:


When to use, notes


Banner, branding


Any content that is complementary, or an aside.


The main content of course!


Any navigational block. If there are more than one, they need to have names for disambiguation.  The annotation needed is aria-label=”name of the navigation”


Any subsection of the main content. They need to have a name. The annotation needed is aria-label=”name of the section”


Pretty self explanatory. 

Solution: visually annotate the regions' boundaries and provide the correct label for each.

Image descriptions

Images must have appropriate alternative text. If the image is meaningful, annotate it with alt=”the meaning of the image,” and if it is not meaningful with alt=””.
Solution: Provide in design annotations the specific alternative text (e.g. 'Alt text="Universal design symbol"') for each image.

Link text

Text of links must meaningfully describe the destination. All links need to clearly and textually describe their function and also be unique within the view.

UI control text

User interface controls must also be labeled with text that meaningfully describes the function and is unique within the view.

Other semantic considerations

In general, all chunks that you can read visual meaning into need to have that meaning expressed in the markup; thus it is important to remind the developer of this. Here are some examples:

Text blocks:

  • If it looks like a paragraph it needs to be code as one (<p>)

  • If it looks like a list, it needs to be coded as one (<ul>  for bullets or <ol> for numbers) - note: some things do not really look like a list, but should be one. Any sequence can be construed as a list, even if it is horizontal.

Annotate tables to ensure the developer uses semantics

  • A column heading row <tr><th scope=”col”>Header label</th>....</tr>

  • A row heading on the row cell that could be the title of the row <th scope=”row”>

  • If there are a lot of tables in the same view, ensure that they have names by annotating with caption=”name of the table”


There is one rule: if an element is in a form, it needs to be a labeled form element, programmatically associated with a form element or with the form itself. This applies to 

  • Form element labels
    <label for=”id of form element”>

  • Informational text

    • Global instructions: either outside of the form or associated with it via
      <form aria-describedby=”id of global message container”>

    • Form element instructions
      <input aria-describedby=”id of information container”> 

  • Error messages associated with form elements
    <input aria-describedby=”id of error message container”>

  • Form group titles: in complex forms, group like form elements with a title
    <fieldset><legend>Title of group</legend>
        …. Form elements (and their labels)
    This is required with radio and button groups, regardless of the complexity of the form.

  • Finally - if the design visually omits a form element label, annotate the form element with:
    aria-label=”name of this input”

Form element attributes:

  • Is the form element required?
    <input required>

  • Is it asking for something that the user has filled out already elsewhere?
    <input autocomplete=”on” name=”type of information needed”> - see complete list of possible values for later.

  • Is the input of a specific type? Is it asking for text, a number, a telephone, an email address, etc? Annotate with the corresponding type (full list in a Mozilla article about input types):
    <input type=”email”>, <input type=”tel”>, <input type=”url”>


Some web pages will respond to user actions by changing the page without loading a new one. Users of screen readers will not perceive the change. Some strategies:

  • Add role=”alert” to alert the user to containers that have appeared

  • Add aria-live=”polite” to containers that change

  • Annotate with “pass focus to new input” if a user action has added a new form element

Evolve your annotation

Annotating designs for accessibility involves a bit of informed guess work and learning on the job. The more you do, the more secure you will be in your assumptions and the more on target will be your recommendations.

We have not scratched the surface of things that can be flagged in annotations to help developers do the right thing. The Figma Annotation plugin is actually a good learning tool, even if you do not use Figma.

If you are involved in reviewing the IT as it is being produced, a quick non-technical heuristic review will unearth many barriers that happen also to be the types of barriers that are really difficult to annotate against.

See these references for more discussion: