DEV Community

loading...

10 ways to improve your forms accessibility

Neha Sharma
UI Engineer ,I love Web,JavaScript, Design System, A11Y, HTML5, CSS3 ,React; Community Advocate and enjoy giving talks and codelabs at the Meetups and conference. I am self-taught calligrapher too.
・4 min read

Forms are very crucial for every website. The reason is they are interactive as well as the connection between the users and products.

Forms are highly used for checkout, payment, feedback, and other details. The form which is not accessible will lead to a hit on the business. Hence, it is important to have accessible forms.

1. placeholder !== label

One of the most common patterns of the form is not having the label. Developers and UX folks assume placeholders would be sufficient for the end-users.

placeholder !== label

This is important for screen-reader users.

Either, have label or aria-label


<!-- WRONG: missing label -->

<input type="text" placeholder="enter your email" />


<!-- CORRECT: option1 Use label or aria-label -->

<label for="email">Enter your email</label>
<input type="text" id="email" placeholder="enter your email" />

<!-- CORRECT: option2 -->
<input type="text" aria-label="enter your email" placeholder="enter your email" />

Enter fullscreen mode Exit fullscreen mode

2. Correct type of input

Not having correct input type.

Do you know HTML5 has a different attribute value of type? The correct type is very important for:

  • Screen readers

  • Mobile users

  • Native error handling

  • Security

  • Native behaviour of inputs. Eg: type="color" will open the color picker.”


<!-- WRONG: wrong use of the input(s)' type -->

<input type="text" placeholder="enter your mobile number" />
<input type="text" placeholder="enter your password" />

<!-- CORRECT: Use correct input type -->

<input type="tel" placeholder="enter your mobile number" />
<input type="password" placeholder="enter your password" />

Enter fullscreen mode Exit fullscreen mode

3. Group your check-box and radio - fieldset & legend

While using checkboxes or radios use fieldset to group them together and legend for their heading.

Screen Reader will read the legend when the user selects an option otherwise it would be only - veg, non-veg.. not the heading


<!-- WRONG: Screen readers won't able to pick the "Enter your prefer meals"-->

<div>
  <h2>Enter your prefer meals</h2>

  <input type="checkbox" for="c1" />
  <label id="c1">Veg</label>

  <input type="checkbox" for="c2" />
  <label id="c2">Non-veg</label>

  <input type="checkbox" for="c3" />
  <label id="c3">Vegan</label>

  <input type="checkbox" for="c4" />
  <label id="c4">Fruit salad</label>

<div>


<!-- CORRECT: Use fieldset & legend to support Screen Readers-->


<fieldset>
  <legend>Enter your prefer meals</legend>

  <input type="checkbox" for="c1" />
  <label id="c1">Veg</label>

  <input type="checkbox" for="c2" />
  <label id="c2">Non-veg</label>

  <input type="checkbox" for="c3" />
  <label id="c3">Vegan</label>

  <input type="checkbox" for="c4" />
  <label id="c4">Fruit salad</label>

<fieldset>

Enter fullscreen mode Exit fullscreen mode

4. Button and links

Buttons are for action and Links are for re-direction.

It is important to understand this. Yes, JavaScript is very powerful but do not swap the usage otherwise:

  • the accessibility will be broken

  • extra code needs to be written


<!-- WRONG: link is getting used as button-->

<a href="#" onClick="submitForm()">Submit</a>


<!-- CORRECT: Semantic tag -->

<button onClick="submitForm()">Submit</button

Enter fullscreen mode Exit fullscreen mode

5. aria-atomic

aria-live announces the dynamic content whenever the content will changes. The screenreader will only read the 'changed' part which could confuse the user.

aria-atomic will read the whole content, not just the changed one


<!-- WRONG: total-price will not be picked by the screen readers when the price will be changed.-->

<!-- This will announce the $ 100 when it will change  -->

<div class="totalPrice" aria-live="polite">
  <span>Total Price:</span> <h2>$ 100</h2>
</div>

<!-- CORRECT: This will announce the "Total price $ 100" whenever the price will change -->

<div class="totalPrice" aria-atomic="true" aria-live="polite">
  <span>Total Price:</span> <h2>$ 100</h2>
</div>

Enter fullscreen mode Exit fullscreen mode

6. describedby

In our forms, when we want to give extra information related to any field we generally use a sub-text or tool-tip.

For screen readers this could be non-accessible, so we use describedby to provide extra information related to the field.”


<!-- WRONG: Additional information regarding field email will be missed by the screen readers -->

<input type="email" aria-label="Enter your email" />
<p>We will use your email for marketing</p>


<!-- CORRECT: describedby -->

<input type="email" aria-label="Enter your email" describedby="emailInfo"/>
<p id="emailInfo">We will use your email for marketing</p>

Enter fullscreen mode Exit fullscreen mode

7. required fields

Whenever we have a required field we use an asterisk to present that. The airstrike is for visual representation only.

For screenreader use the HTML5 attribute required.

  • Assistive technologies support

  • Default validation

  • Default Look & Feel


<!-- WRONG: Only visual cue to required field -->
<label for="email">Enter your email*</label>
<input type="email" name="emailDescription" />


<!-- CORRECT: Use of required for non-visual users too -->

<label for="email">Enter your email*</label>
<input type="email" name="emailDescription" aria-required/>

Enter fullscreen mode Exit fullscreen mode

8. Errors and colors

For errors-state do not use colors only. Use the text too. So, that people with vision (color-blindness) can understand.

Follow:

  • Grouping messages in 1 place

  • Moving focus of the keyboard & SR there

  • Provide a link to the problem field

9. optgroup

In the dropdown, grouping the same option together is important for readability, and keyboard access.

using optgroup will group the same options together.

<!-- WRONG:No grouping of the option. -->

<select>
  <option>Chicken</option>
  <option>Fishe</option>
  <option>Spinanch</option>
  <option>onion</option>
  <option>Kale</option>
  <option>Meat</option>
</select>


<!-- CORRECT: Use optgroup to group the same fields-->


<select>
  <optgroup label="non-veg">
    <option>Chicken</option>
    <option>Fishe</option>
    <option>Meat</option>
  </optgroup>
  <optgroup label="veg">
    <option>onion</option>
    <option>Kale</option>
    <option>Spinanch</option>
   </optgroup>
</select>
Enter fullscreen mode Exit fullscreen mode

10. focus or outline

A clear visual cue is important for focus while using the keyboard. Focus and outline are the CSS property that can be used to enhance the visual cue.

  • Never make outline:0

  • If making outline:0 then add the other properties to support the visual cue


/* WRONG: Do not  turn off the outline */

*:focus{
   outline: 0;
}

/* OPTION 1: Custom focus/outline can be added */

*:focus{
    border: 1px solid pink;
    box-shadow: 0 0 10px pink
    outline: 0;
}

/* OPTION 2: customizing outline value */

*:focus{
    outline: 1px solid blue;
}

Enter fullscreen mode Exit fullscreen mode

Happy Learning!!

You can follow me at twitter

Discussion (5)

Collapse
rafavls profile image
Rafael

Great article!

Collapse
ashishmangla0 profile image
ashishmangla0

what ARIA we can use for infinite loading ??

Collapse
hellonehha profile image
Neha Sharma Author
Collapse
francoisaudic profile image
francoisaudic

When you talk about « describedby », I think you mean « aria-describedby » or i am wrong ?

Collapse
hellonehha profile image
Neha Sharma Author

yes, arai-describedby.

you are correct.