ArcGIS Blog

Developers

ArcGIS Maps SDK for JavaScript

Build Accessibility into your Web Maps with ArcGIS Maps SDK for JavaScript

By Kitty Hurley and Kelly Hutchins

A map centered on the United States lower 48 states, which summarize the count, and rates, of accidental deaths in each state.

When building interactive maps, which are very visual in nature, apps can include improvements so they can reach wider audiences. Interactive map users benefit when context is provided as they interact with the map. For example, providing context when the map has loaded in the display, what the map’s data includes, and and map’s purpose.

By providing additional context to audiences with low, or no vision, mapping apps can be used more universally. Similar strategies can also support lower internet speed connections, where context is provided if the content takes longer than expected to load in the app.

Live regions

While a fully sighted user may be able to indicate when the map has loaded on the page, users who rely on assistive technologies, such as a screen reader, may not know when the map has loaded in the app. When content dynamically changes, its context can be provided to a user through assistive technologies with an ARIA live region.

Add a live region

To provide similar on-demand context when the map has loaded to assistive technologies, a live region can be added to the map. Add an aria-describedby attribute to the parent element of the map, such as the document’s body. The aria-describedby attribute will be associated with another element’s “id” on the page, where the description will be provided. The element can also include the aria-live attribute set to “polite” so users receive the information when they are idle. By adding an aria-describedby attribute, those navigating an app with assistive technologies will have the ability to better understand the content in the app.

<body aria-describedby="map-loaded">
  <p id="map-loaded" aria-live="polite" class="sr-only"></p>
</body>

To visually hide the description from users, add a “sr-only” class to the element. The class will still contain the description’s text contents, but will be visually hidden in the app via CSS:

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}

To use a similar strategy for low internet speeds, the CSS class above could be omitted to provide both visual and descriptive information to users, in the event the messaging could be useful visually and to assistive technology users.

Dynamically add the description

Update the live region with information from the web map after the view is ready with the web map’s title, Accidental Deaths, and add it to the live region:

const mapLoadMsg = document.getElementById("map-loaded");

await view.when();
mapLoadMsg.innerText = `${map.portalItem.title} map has loaded.`;

Create a map description

The map can also contain a description when a user is actively focused on the map with assistive technologies.

Similar to the live region, a new element can be added to contain the map’s description. Add the same “sr-only” class to the element, where the description will be visually hidden to users:

<p id="map-description" class="sr-only"></p>

If an app contains a web map, the webmap’s snippet or description can be used to update the “map-description” element, which provides additional context on the map’s purpose and contents to the user.

const mapLoadMsg = document.getElementById("map-loaded");
const mapDescription = document.getElementById("map-description");

await view.when();
mapLoadMsg.innerText = `${map.portalItem.title} map has loaded.`;
mapDescription.innerText = map.portalItem.snippet;
const surfaceEls = [...document.getElementsByClassName("esri-view-surface")];
surfaceEls.forEach((surfaceEl) =>
  surfaceEl.setAttribute("aria-describedby", "map-description")
);

To add the description to the map view’s surface node, use “getElementsByClassName” to return elements from the “esri-view-surface” class. There is only one element, but the method returns an array of results. The spread syntax (…) iterates through the array, which applies the description to the element.

Explore the demonstration app

Below is a demonstration app, with the code and app available on GitHub.

To test the app:

  1. Enable a screen reader, such as NVDA (free) or JAWS on Windows, or VoiceOver (included) on MacOS.
  2. Open the app in a browser window. For VoiceOver, Safari is MacOS’ supported browser.
  3. Navigate into the app and explore the live region and map description.

Note: Not all assistive technologies support the aria-describedby attribute. For example, Narrator does not. For full supporting information of aria-described by, visit a11ysupport.io.

Share this article

Subscribe
Notify of
1 Comment
Oldest
Newest
Inline Feedbacks
View all comments
Rohit Venkat Gandhi Mendadhala(@rohit-mendadhala_tfsgis)
October 1, 2020 9:49 am

Can you help us understand what are the variables ‘ses_iam_sk’ and ‘ses_iam_ak’ in your script? Are these the username and password for the email? I am guessing these to be simple email service access key and secret key from AWS? Wondering how we can use them in Azure platform. Thank you

Taylor Teske(@tteske)
October 9, 2020 6:07 am

Hey Rohit, that is correct. Those are the SES access and secret keys from AWS. Azure does not provide a SES and requires third-party solutions, like Twilio’s SendGrid: https://docs.microsoft.com/en-us/azure/architecture/aws-professional/messaging.

Ahjung Kim(@ahjung-kimstantec-com_stantec)
October 9, 2020 5:54 am

@Taylor Teske This is very helpful – thank you so much for posting this. Any chance we can find a repository for your sample code used in this article? That would help out beginners like myself greatly.

Taylor Teske(@tteske)
October 9, 2020 6:10 am
Reply to  Ahjung Kim

Hey Ahjung, I don’t have anything in GitHub currently, but that is certainly a great idea! When I get some time, I’ll try to get something in GitHub. The first example was developed from a script for a customer, so I may need to modify it a bit.

Taylor Teske(@tteske)
October 15, 2020 5:30 am
Reply to  Taylor Teske

Hey Ahjung, the following repo includes the sample code: https://github.com/tatornator12/Azure-Functions-ArcGIS-Examples. As mentioned, I had to remove most of the Timer Trigger code.

Julian Inskip(@jxi-2)
June 4, 2022 12:58 pm

Hi Taylor. Is it possible to get the payload coming from the Survey123 entry? I would like to access the information being submitted in the form within my python Azure Function.

Thanks, Julian

Daniel Mallett(@dmallett)
September 26, 2022 1:15 pm

i can’t seem to post a link here in the comments but if you are having issues publishing see community.esri.com and search for suddenly can’t build and deploy python azure

Related articles