Lessons learned when developing accessibility in prices at Mercado Libre

Martín Di Luzio
Mercado Libre Tech
Published in
7 min readMay 19, 2022

Today, May 19, it is “Global Accessibility Awareness Day” (GAAD), so we think it is a good moment to share the lessons we have learned to improve user accessibility to the products we develop at Mercado Libre.

Product prices can be reasonable, that is to say affordable, but they must be well communicated. Immersed in a “user centricity” culture, we seek to improve the browsing experience of our site’s users. That is why we have taken on the challenge of making prices “accessible” to screen readers, assistive technology that represents text and image content like voice output or Braille. At Mercado Libre we started a process to improve accessibility to our products, understanding that many of the obstacles and barriers come from the way in which software developers think, design and build products and services.

A cross-cutting issue in Mercado Libre ‘s user experiences that has remained current over time is Price. We’ve noted that in its varied available versions and implementations, it was being displayed to screen reader users in a poorly understandable way and with inaccurate values.

In order to generate interfaces that can be understandable, perceivable, operable and robust, we’ve started implementing accessibility improvements in our Andes Design System. In this article, we put the focus on a specific component for the web: the Price component.

What were our first steps?

The main idea was to develop a Price component, AKA MoneyAmount, that teams could adopt, with its different variants springing from a unique and consistent approach in Mercado Libre. This component added great learning about assistive technologies, browsers, implementations and concrete experiences.

The challenges we faced

This was the scenario when we started our journey:

The price on a product page announced by VoiceOver on Mac OS.

Verbalization through screen readers depends on several factors:

  • the browser (user agent) and its way of displaying the accessibility tree,
  • the operating system,
  • the screen reader and its settings,
  • the voice used (synthesizer). The same screen reader, on the same system, operating with the same browser but with different voices, can read the same text in very different ways,
  • the syntax and formatting of the code.

We’ve specifically found the following challenges:

Focus jumps in screen reader browse mode

When the user scrolls through the price region, there are different jumps in the sequential navigation that display currency, values and characters separately, which that makes it a little unintuitive and inconsistent.

Currency “$”

The currency symbol “$” is verbalized/read as “dollars” by the screen reader, regardless of the language or region. This generates inconsistency with the country. The screen reader’s pronunciation dictionary could replace this behavior but we think the solution should not be left to the user.

Integer and decimal separator character

Each country or region formats figures in different ways using separator characters for integers (with a thousand separator) and decimals to identify the relationship between digits of the same price. For example, in Mexico, the thousands are separated with a comma, while in Argentina they are separated with a period.

Reference: Decimal separator — Wikipedia

Previous prices and discounts without context

Generating context for the user to recognize the price variation is essential in decision making and this was not being communicated at all.

Price crossed out to identify a previous value of the price.
Information should not be conveyed only visually; a crossed-out value does not convey its purpose to screen readers.

So what did we do?

After an exhaustive analysis of the situation, we started with a validation stage based on 3 pillars: specifications and standards, validation of references in the field, and tests with screen reader users.

Specifications

In the official HTML and accessibility documentation provided by WHATWG and W3C WAI-ARIA, we obtained information and authoring practices for different components. Even if we knew that these recipes are not perfect and do not always offer the best experiences to all users, we capitalized on them as a starting point for the analysis.

They are necessary reference sources that allow us to validate the quality of our code and, although we know that the specification support is not always stable, we wanted to be accurate in our implementation.

Technical validations

We wanted to achieve a robust solution in verbalization, although we knew there was no general solution. Yet, it was necessary to avoid expressing the wrong price to screen reader users. Thus, we first ran tests with separator characters and observed unstable results depending on combinations of speech engines (TTS) or punctuation settings in screen readers.

Table with some tests carried out combining screen readers (JAWS, NVDA , Voice Over and Talkback) and separators (space, comma, period and no separator), indicating the support they provide in their pronunciation. It is observed that Talkback is the one that has full support for any combination of separators, and if a separator is not used, we get the most robust result (more consistent pronunciation between the screen readers used).
Table of tests performed with different screen readers to validate some cases.

References:

  • * verbalizes only digits to the left of the cent separator, ignoring the remaining digits
  • “-” verbalizes digit by digit
  • “ok” verbalizes hundreds, thousands, millions
  • “W/S” without separator

Then, we analyzed documentation from different accessibility referents and documentation of solutions applied by teams outside Mercado Libre, but we did not find specific implementations for our case.

Documents from accessibility teams

Some references:

It is important to note that browsers do not always provide the expected support for screen readers, even after the implementation of the accessibility specifications generated by WAI-ARIA. For this reason, it is important to validate with Accessibility Support to find a widely supported solution.

User experience

Last but not least, the implementations we generated needed to be validated by users in order to identify if the experience was being effective. To this end, we relied on organizations such as Nahual IT and Fundación itgrarte to help us recognize key points.

How did we implement it?

The first thing we did to solve the focus jumps in browser mode, currency “$”, and integer and decimal separator characters was to remove the visual price representation from the browsing for screen reader users. In order to do so, we used the aria-hidden attribute on the container element. This ARIA attribute allows us to hide an element from the accessibility tree used by assistive technologies so that they ignore it.

Observations: The price is made up of different classes that allow you to apply style to your visual presentation.

<div class="" aria-hidden="true">
<span class="currency">$</span>
<span class="fraction">22.999</span>
<span class="cents">08</span>
</div>

It is important to clarify that this attribute should not be used in keyboard focusable elements or with tabindex=”0" since it generates inconsistency between the focus with TAB key and the scanning mode of the screen readers that will ignore the element.

After analyzing the challenges we had in finding a robust solution as well as the tests performed, we decided to verbalize the price in Spanish with the following format in pesos and cents:

{integer} pesos with {decimals} cents

Where {integer} is the number without thousands. For example: 10000 and {decimals} is the number of cents.

To achieve the specific verbalization to the screen reader, we use a CSS Screen Reader Only class that allows us to visually hide the expression, but that is achievable in the navigation of these technologies.

<style>
.sr-only {
border: 0;
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1;
margin: 0 -1px -1px 0;
overflow: hidden;
padding: 0;
position: absolute;
width: 1;
}
</style>

Our code block will finally look like this:

<div class="sr-only">22999 pesos con 08 centavos.</div>
<div class="" aria-hidden="true">
<span class="currency">$</span>
<span class="fraction">22.999</span>
<span class="separator">,</span>
<span class="cents">08</span>
</div>

Disclaimer: Screen readers do not generally require or need the addition of verbosity to textual content, but they do for our implementation.

In some of the tests evaluated, the aria-label attribute was intended to be applied directly to assign a programmatic name to the price container:

<div class="" aria-label="22999 pesos con 08 centavos.">
<span class="currency">$</span>
<span class="fraction">22.999</span>
<span class="separator">,</span>
<span class="cents">08</span>
</div>

This is also read only by screen readers, but the ARIA specification indicated that it should only be applied to elements with implicit or explicit roles, thus disregarding this implementation.

As regards the challenge of “Previous prices and discounts without context”, in order to solve the statement of a current price and a previous one, we applied the same approach to provide context in price differentiation by adding the text “Before” and then the text “Now” to the current price.

Since the native HTML <s> tag (visually strikethrough text) does not announce any semantics to screen readers, at least in the tests performed and in the validated documentation, we generated this code block:

<div class="sr-only">Antes: 24999 pesos.</div>
<s class=”” aria-hidden=”true”>
<span class="currency">$</span>
<span class="fraction">24.999</span>
</s>
<div class="sr-only">Ahora: 22999 pesos con 08 centavos.</div>
<div class="" aria-hidden="true">
<span class="currency">$</span>
<span class="fraction">22.999</span>
<span class="separator">,</span>
<span class="cents">08</span>
</div>

This is the final result of all this process:

The price on a product page advertised by VoiceOver on Mac OS with upgrades.

With this implementation we have achieved accurate price pronunciation, prioritizing the sensitivity of the data and not a solution for a particular screen reader.

Learnings

Context is essential to perceive information and to be able to generate coherent experiences for all users. We understand that it is important to prevent programmatic information from differing from visual information and in order to do so, we’ve validated expected behaviors with the experience of users of assistive technologies.

We’ve also discovered that specifications differ between browsers and screen readers, as well as that support and adoption of new or improved standards do not always go hand in hand, and that browsers compensate for poor implementations by forcing unsound decisions, that is, with solutions that work well for some but not for others.

Further, authoring practices, approaches or recipes do not always generate good experiences and it is important not only to evaluate consistency within our products, but also in the most widely used products on the market.

Throughout this process, we have generated knowledge and experiences that we want to share with the community. We have also been the recipients of good practices generated around other products. In this way, we were able to work together and in synergy so as to put an end to this paradox: high or low prices, but accessible.

Lastly, I want you to also learn everything we learned on the Android platform while we improve the accessibility of prices from the hand of Juan Ignacio Unzurrunzaga.

--

--