|||

Video Transcript

X

Designing for Accessibility: Contrast Ratio

This is the second post in a two-part series about accessibility. The first post shares why designing for accessibility is important to us and why we encourage you to incorporate it into your software design process.

Heroku’s first accessibility initiative was to reach Level AA for luminance contrast ratio as defined by the internationally recognized best practices of the Web Content Accessibility Guidelines (WCAG) 2.0. This ratio guarantees the legibility of text against its background, in order to ensure all users can perceive Heroku’s user interfaces equally.

This benefits people with color-vision deficiencies (like Deuteranopia or Protanopia which affect 7 to 12% of men), age-related low vision conditions (like macular degeneration or diabetic retinopathy) and those with presbyopia, the natural aging process of, well, needing glasses. These conditions reduce sensitivity to contrast, and in some cases reduce the ability to distinguish colors.

Color is a key aspect of design but it's clearly not perceived the same way by everyone (color even signifies different things to different cultures). That's why it's important to offer a minimum contrast and not rely exclusively on colors for relaying information or functions.

The specifics of the WCAG guidelines (1.4.3 Contrast) define that:

  • All normal-sized text require a luminance contrast ratio of at least 4.5:1, and
  • All large-sized text require a luminance contrast ratio of at least 3:1

These guidelines served as a pretty SMART goal for this initiative, driving the effort from the first proposal to the final deployment.

The Design Proposal

Audit

Our first obvious next step was to perform an audit of our existing color palette. We used Contrast Grid to map out all the possible text and background color combinations the color palette could offer.

Grid of Heroku’s previous palette combinations and their respective contrast ratios
Grid of Heroku’s previous palette combinations and their respective contrast ratios

We only use a very small percentage of color combinations from that grid but it was a helpful tool to quickly see which combos reached the minimum contrast ratio and which didn’t.

Proposed changes

We then listed all the combinations that needed more contrast and proposed new colors to meet the minimum. These are just a few examples of the proposed changes.

Comparison of legibility and contrast ratios of our old and proposed new light gray colors Comparison of legibility and contrast ratios of our old and proposed new gray colors Comparison of legibility and contrast ratios of our old and proposed new blue colors
Comparison of legibility and contrast ratios of our old and proposed new gray and blue colors

In order to keep a consistent selection of shades from the same gray hue, we realized that we needed further changes to the palette. So we ended up changing two other tones and getting rid of one, since a darker starting point meant less noticeable variation.

Comparison of our old and proposed dark grayscale palette in which the only changes are two new color values for our lightest grays
Comparison of our old and proposed dark grayscale palette in which the only changes are two new color values for our lightest grays
Comparison of our old and proposed dark grayscale palette in which we get rid of one of the lightest colors
Comparison of our old and proposed dark grayscale palette in which we get rid of one of the lightest colors

We proposed several other changes on the complete grayscale palette, like getting rid of colors, defining which colors could be used with a light or dark background or changes in names.

Comparison of our old and proposed complete grayscale palette in which we get rid of two colors and change multiple color values and names
Comparison of our old and proposed complete grayscale palette in which we get rid of two colors and change multiple color values and names

Final grayscale palette proposal:

Final complete grayscale palette proposal with all the proposed changes
Final complete grayscale palette proposal with all the proposed changes

These changes gave us a solid, consistent, and above all, accessible color palette for our product.

Grid of Heroku’s new palette combinations and their respective contrast ratios showing better results than the previous one
Grid of Heroku’s new palette combinations and their respective contrast ratios showing better results than the previous one

Once we began the implementation planning process, we realized how much overhead all these small changes added and how long it would take to implement them on all our product, websites, and other marketing graphics. We then decided to scope it down and came up with a second proposal.

This new one kept the changes to the darker grays but didn’t remove any color or change any name — it maintained unnecessary colors and inconsistent names but solved our accessibility concerns with a time investment we could afford.

Comparison of our old complete grayscale palette with our first and second proposals
Comparison of our old complete grayscale palette with our first and second proposals

The Implementation

Heroku’s graphic user interfaces (GUIs) are built using our deceptively simple design and icon systems, Purple 3 and Malibu. Purple 3 takes a functional approach to CSS, using the popular Tachyons framework as its foundation and providing a carefully composed set of utility classes (that is to say, CSS classes that do one very focused thing). Malibu complements Purple 3 by providing a library of icons lovingly crafted by our design team. Together, Purple 3 and Malibu provide everything we need to build our GUIs in a manner that is flexible whilst maintaining consistency.

The proposed new color palette touches every part of our GUIs so we knew we couldn’t simply release new versions of Purple 3 and Malibu and hope for the best—we needed an approach that would allow us to rigorously audit the changes before releasing them to customers. Fortunately, we happen to build a platform that provides the ideal tool for this kind of situation: Review Apps.

When our design team opened their pull request introducing the new color palette to Purple 3 and Malibu, the Heroku platform automatically generated a review app containing the new production-ready CSS and SVG assets on a dedicated URL. To try the new assets out in our Dashboard GUI, all we needed to do was open a pull request swapping in the new URL and, hey presto, a review app demonstrating the new color palette sprang into existence ready to be audited.

It’s not always easy to predict how the components of a design system will end up being combined in practice, especially in a large app with many features added over many years. We had to ensure we were improving the legibility of common elements such as form labels, notifications, and warnings, but also more exotic elements such as our metrics charts. For the most part, we were very happy with how the improvements worked in practice and were even happier to see the number of color contrast violations in our GUIs drop by an order of magnitude. Straying slightly outside of the proposed new grays, we discovered that finding a shade of orange that met our standards for contrast, legibility, and aesthetic elegance was surprisingly challenging!

Table showing color contrast violations across Heroku Dashboards’s top 10 most visited pages (checked with axe-core 3.2.2)
Color contrast violations across Heroku Dashboards’s top 10 most visited pages (checked with axe-core 3.2.2)

Note: these numbers are adjusted slightly to account for a particular element that isn’t audited accurately by axe-core at present. They are also not universal, but rather reasonably representative of using Heroku with an average number of apps and other entities on display.

Once our teams had taken the time to audit each of our GUIs and we were confident we hadn’t regressed legibility in any areas, we rolled out the change to customers. In the end, a mix of solid research, theory, tools, and attention to detail got us to where we wanted to be—a GUI that is every bit as elegant as before but now markedly more accessible.

The Result

A small change with a big impact

The new color palette has been rolled out across all of the Heroku Dashboard. When you visit any page in the Dashboard, you will find improved color contrasts that are a result of the work that has been done. While it can be hard to discern the improvement in legibility from one day to the next, the impact is much easier to spot when looking at the before and after interfaces side-by-side.

Below are two identical screenshots of the Spaces section of the Heroku Dashboard with the old colors on the left and the new colors on the right. Note the darker gray (1) and blue (2) text.

Screenshots of Heroku Spaces section of Dashboard showing impact of increased contrast on gray and blue text
Screenshots of Heroku Spaces section of Dashboard showing impact of increased contrast on gray and blue text

The screenshots of the Dashboard below show the impact of increased color contrast on other elements beyond text such as badges (1) and icons (2).

Screenshots of Heroku Dashboard showing impact of increased color contrast on badge and icon elements
Screenshots of Heroku Dashboard showing impact of increased color contrast on badge and icon elements

Our color palette changes are reflected equally in mobile browsers, where small screen sizes and lower resolution can present additional challenges to legibility. Below are before and after examples of our review apps page in a mobile browser. For example, compare the "REVIEW APPS" (1) and "Create a review app from a branch" (2) text.

Before and after examples of our review apps page in a mobile browser
Before and after examples of our review apps page in a mobile browser

We are proud that Heroku's Dashboard is now more legible by people with low contrast sensitivity or color blindness, that it is more legible in different lighting conditions, and that it is easier to read by everyone.

What’s Next?

Invest in tooling to keep us accessible

We use both Ember and React to build our web interfaces and happily both communities take accessibility extremely seriously. For the purposes of this post, we’ll focus on Ember’s tooling.

In the Ember community, the Ember A11y group is responsible for advocacy and tooling around accessibility. Among the tools they maintain is ember-a11y-testing, a tool that plugs into Ember’s opinionated testing framework and makes it easy to run an accessibility audit (powered by industry-standard axe-core) at key moments during acceptance tests. In practice, it looks like this:

test('browsing apps', async function(assert) {
  await visit('/apps');

  a11yAudit();

  assert.dom('.apps-list').containsText('My App');
});

If we were to introduce an accessibility violation (for example, insufficient color contrast) then our test will fail and tell us exactly what we’ve done wrong:

Example of a failing accessibility test
Example of a failing accessibility test

To make extra sure we’re using these tools diligently, we’re also experimenting with adding linting rules to ensure acceptance tests contain accessibility audits:

Example of linting rule failure
Example of linting rule failure

We’re incredibly excited to be bringing these tools to our development workflow, both as a means to keep our apps accessible and because they play an important role in teaching accessibility best practices.

Accessibility best practices across our UIs

This work is one step in making Heroku more accessible and we know there is more to do. There are other aspects of accessibility for us to consider for the Dashboard. We also have a number of other user interfaces to consider beyond the Heroku Dashboard, including the Elements Marketplace, Dev Center, and our Heroku Command Line Interface. Our next step is to complete an audit that will give us a fuller understanding of accessibility across our product surface area and the work to be done.

Invitation for feedback

We’d love to get your feedback and learn about what else you’d like to see. Drop us an email to feedback@heroku.com.

Originally published: August 21, 2019

Browse the archives for engineering or all blogs Subscribe to the RSS feed for engineering or all blogs.