Promote Equality by Building Accessible Content

We all strive to become more inclusive but as developers, we can easily overlook one of inclusivity’s many aspects: accessibility. In this blog post, we’ll look at a few common bad practices that make content inaccessible and how to turn them around using some practical tips. With these best practices and some additional coding, along with Lightning Base Components and the Lightning Design System, you can create and deliver accessible content.

What is accessibility? Accessibility is ensuring people with disabilities can perceive, understand, navigate, interact with, and contribute to any application. That is, equality of access to all aspect of our application’s functionality and content.

We can easily forget that accessibility should always be an explicit requirement. It is easier to implement when it is already baked into requirements rather than fixing the bugs at the last minute.

Accessibility is even more relevant than you think

When we mention accessibility, we tend to associate it with visible and permanent disabilities such as paraplegia or blindness. However, disabilities are much more frequent that we think.

A disability is defined by any physical or mental condition that undermines one’s ability to perform certain tasks. According to a similar broad definition of disability, the U.S. Census Bureau estimates that nearly 1 in 5 people have a disability in the U.S. This figure may look exaggerated, but it can be better understood by having a closer look at some common biases.

A first bias is that we generally underestimate the frequency of certain disabilities. For example, let’s consider a “well known” disability that affects the use of software: color blindness. Did you know that 1 in 12 men are considered color blind (For women, the condition affects 1 in 200)?

Hearing loss is a similar example. Are you aware that approximately 15% of American adults suffer from it?

A second prevalent bias is that we generally do not account for all types of disabilities. Disabilities fall into multiple categories and some of them are invisible or temporary. For example, you can be temporarily disabled if you break your arm or undergo eye surgery.

As a consequence of these biases, we may inadvertently design content that excludes a certain number of users or that is difficult for them to access. This has a negative impact as it deprives these individuals from their independence and hinders them in their daily life. Inaccessible content would be similar to not being able to access your bank account or health record on your own.

Because disabilities impact a significant portion of the population, governments and international bodies are acting in favor of accessibility. In the software industry, this effort translates into various accessibility standards and regulations.

If you are working for the public sector, there is a good chance that some of these apply to your projects. However, more and more private sector companies are also prioritizing accessibility. If you are not a User Experience (UX) specialist, consider the Web Content Accessibility Guidelines (WCAG) 2.0 as a starting point (conformance level AA is the industry standard).

For the sake of brevity, we will not cover all these guidelines in this article, but we will point out some bad and best practices.

Bad practices (or what most of us do everyday)

Without being exhaustive on accessibility bad practices, let’s take a look at a basic example to highlight some common problems. If you develop a simple form with no consideration for accessibility, you could write something like this:

<div class="slds-box">
  <div class="slds-media slds-media_center">
    <div class="slds-media__figure">
      <lightning:icon iconName="action:new_contact" size="medium"/>
    </div>
    <div class="slds-media__body">
      <p>New Contact</p>
    </div>
  </div>

  <div class="slds-form-element">
    <label class="slds-form-element__label" for="text-input-id-1">First Name</label>
    <div class="slds-form-element__control">
      <input type="text" id="text-input-id-1" class="slds-input" />
    </div>
  </div>

  <div class="slds-form-element">
    <label class="slds-form-element__label" for="text-input-id-1">Name</label>
    <div class="slds-form-element__control">
      <input type="text" id="text-input-id-1" class="slds-input" />
    </div>
  </div>

  <div class="slds-form-element">
    <label class="slds-form-element__label" for="text-input-id-1">Title</label>
    <div class="slds-form-element__control">
      <input type="text" id="text-input-id-1" class="slds-input" />
    </div>
  </div>

  <div class="slds-button slds-button_brand slds-m-top_medium">Create Contact</div>
</div>

If you deploy this code, this is what happens if a user tries to use your form with a screen reader (an app that presents a UI into a non-visual form such as text-to-speech):

If you were a visually impaired person, how could you use this form?

The good news is that it does not take a lot of efforts to make this form accessible. We are going to review several WCAG recommendations that help to achieve this.

Accessible content is simple to create

WCAG states that accessible content must respect four types of guidelines. Content must be perceivable, operable, understandable, and robust.

Perceivable

Perceivable – Information and user interface components must be presentable to users in ways they can perceive.

Ensuring that content is perceivable is critical for accessibility. For example, visually impaired users need the help of assistive technologies such as magnifiers or screen readers to access content. These technologies rely on properly structured code.

When looking at the perceivable aspect of our sample form, the first problem that comes to light is that we do not provide a textual alternative to the use of images (the “new contact” icon).

Images need to provide an HTML alt attribute in order to provide a textual description to screen readers. If the attribute is missing, the assistive technology will read out the file name and this will result in a poor user experience.

An exception to this requirement is for decorative images. In that case, do not omit the alt attribute but use an empty value (alt="") instead.

Going back to our demo code, we need to add an alternativeText attribute on the lightning:icon component to make it accessible. This generates the HTML alt attribute.

<lightning:icon iconName="action:new_contact" size="medium" `alternativeText="Contact icon"`/>

Another important cause of perception issues is the use of a non-accessible color palette. When building a user interface, designers need to maintain a sufficient color ratio in their theme. If you are using Salesforce Lightning Design System (SLDS), you are already working with fully accessible color palettes throughout the Lightning Experience. If not, there are online tools that can help you ensure that your colors are accessible.

As a general rule, never use color as the only means to convey a message. For example, do not solely rely on a red border to indicate that a field contains invalid input. Add a text label or an accessible icon to indicate an error.

Operable

Operable – User interface components and navigation must be operable.

Maintaining operable content implies that you can access and interact with your content while replacing the mouse and/or keyboard with alternative input methods such as voice controls.

A basic rule to make your content operable is to use HTML with the right semantic meaning.

For example, use the right tags for interactions:

  • <button> tag for submitting forms or modifying something in a page
  • <a> tag to navigate inside a page or to another page.

A common mistake is to use other elements such as <div> or <span> with an onclick attribute for interactions as these elements do not receive keyboard focus without additional coding.

If you need to trigger an action on an image, wrap it in a <button> or an <a> tag and control the elements’ appearance with CSS.

In our sample code we use a div with a slds-button CSS class to submit the form, but we should use either a button tag or a lightning:button Lightning Base Component to make it accessible.

HTML example:

<button class="slds-button slds-button_brand">Create Contact</button>

Lightning Base Component example:

<lightning:button label="Create Contact" variant="brand"/>

Understandable

Understandable – Information and the operation of user interface must be understandable.

Understandable content implies that it can be read by a user and also be presented by the means of assistive technology. Understandable content also helps users avoid and correct mistakes.

The first thing that needs to be done to create an understandable form is to provide label tags for each input. These help assistive technology such as screen readers to present the UI. Providing placeholder tags alone is not enough.

In our sample code we did include these label tags, but we made a very common mistake: we just copy/pasted the SLDS template without updating it. This causes two problems which break the accessibility of our form:

  • values of the id attribute of our input elements are duplicated.
  • values of the for attribute of our label elements are not matching the right input elements.

To fix this, we can use distinct id values or we can replace the form’s HTML elements with some lightning:input Lightning Base Components.

HTML example:

<div class="slds-form-element">
  <label class="slds-form-element__label" for="FirstName">First Name</label>
  <div class="slds-form-element__control">
    <input type="text" id="FirstName" class="slds-input" />
  </div>
</div>

Lightning Base Component example:

<lightning:input type="text" name="firstName" label="First Name"/>

If you write your own HTML components, you must use id values they are unique across an entire page. An easy way to do this is to generate them dynamically by using the unique identifier of the Lightning component as a prefix like so: id="{!globalId + '_footer'}".

If you wish to hide input labels for a specific UI design, do not hide them with CSS (display:none or visibility:hidden) as this will break accessibility. Apply the slds-assistive-text class. It will safely hide the label while keeping it available for assistive technology.

Another good practice that helps to maintain understandable content is the use of the aria-describedby attribute to link inputs with error messages or help text. This attribute works in the same way as the for attribute of the label tag: it points to the id of the element it describes.

Robust

Robust – Content must be robust enough that it can be interpreted reliably by a wide variety of user agents, including assistive technologies.

Robustness is guaranteed by the use of valid HTML5. Modern web browsers are able to render invalid HTML up to some point, but assistive technologies are more sensitive to invalid markup.

IDEs will do most of the work to assist you, but here are some basic recommendations to ensure that your markup is valid:

  • Avoid duplicate attributes for a given tag unless it is allowed in its specification.
  • Use unique id attribute values.
  • Properly place opening and closing tags for your elements.

Testing

The best way to understand how accessible your content is is to try it out.

For Mac users, macOS has a built-in screen reader, VoiceOver. Windows doesn’t have an integrated tool, but there are some great free tools available, like NVDA.

If we had tested our previous form with a screen reader, we could have easily highlighted some accessibility issues. Let’s take VoiceOver as an example. VoiceOver lets you cycle through the page elements by pressing the tab key. It reads and writes information about the active element.

Here is what we can see/hear with VoiceOver:

While this form has three input fields, VoiceOver is only able to display one label. It identifies the remaining two fields as just “input.” It also fails to see both the form header and the button.

After fixing our form’s accessibility with the best practices we mentioned earlier, we obtain the following code:

<div class="slds-box">
  <div class="slds-media slds-media_center">
    <div class="slds-media__figure">
      <lightning:icon iconName="action:new_contact" size="medium" alternativeText="Indicates approval"/>
    </div>
    <div class="slds-media__body">
      <p role="heading" aria-level="1" tabindex="0">New Contact</p>
    </div>
  </div>
  <br/>
    
  <div class="slds-form-element">
    <label class="slds-form-element__label" for="FirstName">First Name</label>
    <div class="slds-form-element__control">
      <input type="text" id="FirstName" class="slds-input" />
    </div>
  </div>

  <div class="slds-form-element">
    <label class="slds-form-element__label" for="Name">Name</label>
    <div class="slds-form-element__control">
      <input type="text" id="Name" class="slds-input" />
    </div>
  </div>

  <div class="slds-form-element">
    <label class="slds-form-element__label" for="Title">Title</label>
    <div class="slds-form-element__control">
      <input type="text" id="Title" class="slds-input" />
    </div>
  </div>

  <button class="slds-button slds-button_brand slds-m-top_medium">Create Contact</button>
</div>

We can run VoiceOver on this new version and see that our component is now fully accessible.

In addition to testing, we can use audit tools like aXe Chrome Plugin. Once installed in your browser, it scans your page, lists issues, and provides tips to fix them.

Testing is easy to do with these tools, plus it helps you understand which parts of your content are not accessible. Give it a try on one your components!

One last thing that you can do is to unplug your mouse. If you’re not able to use your UI with just a keyboard, then your content isn’t fully accessible. This issue is not solely related to accessibility alone–lots of users love to use keyboard shortcuts. Fixing this will also give these users an awesome keyboard experience!

Conclusion

Building and delivering accessible content does not cost much time or money if you follow the best practices we listed in this article. In short, we recommend that you rely on the combination of the Lightning Design System (learn more about it on Trailhead) and Lightning Base Components to build accessible UIs.

If you want to build your own theme, remember that SLDS can easily be customized with design tokens. This provides a safer alternative to building an accessible theme from scratch.

Lightning Base Components generate accessible HTML but it is your responsibility to properly configure certain attributes such as distinct id attributes or the alternativeText attribute on lightning:icon.

Feel free to explore this demo that presents two versions of the same form: a poorly accessible version and a fully accessible one.

Thank you for reading this post and for helping us to promote equality and inclusiveness.

Resources

About the authors

Fabien Taillon

Fabien Taillon is a Salesforce MVP, and CTO at Texeï. He has been working on the Salesforce Platform since 2009. He is co-organizing the Paris Salesforce Developer Group and community-led event French Touch Dreamin’.
You can follow him on Twitter @FabienTaillon and on his company’s blog: blog.texei.com.

Philippe Ozil

Philippe Ozil is a Developer Evangelist at Salesforce where he focuses on the Salesforce Platform. He writes technical content and speaks frequently at conferences. He is a full stack developer and a VR expert. Prior to joining Salesforce, he worked as a developer and consultant in the Business Process Management (BPM) space.
You can follow him on Twitter @PhilippeOzil or check his GitHub projects @pozil.

Leave your comments...

Promote Equality by Building Accessible Content