Color contrast: beyond text
Tags: a11y, css
Published: 2020-06-22 18:15:52

---
title: Color contrast: beyond text
published: true
description: Low color contrast text is a huge accessibility problem... but low color contrast issues are not exclusive to text.
tags: a11y,CSS
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/ulq9c7vi0750sq9lcrhx.png
series: Web Accessibility with CSS
---

High color contrast requirements [apply to more than just text](https://www.w3.org/WAI/WCAG21/Understanding/non-text-contrast.html). Many other elements are also subject to color contrast requirements:

- The area of a button should be easy to identify.
- Icons should be visible and distinguishable.
- Text in images should follow the same readability and contrast checks as regular text.
- Etc.

In this post, we are going to review some of them, explain common mistakes, and ways to fix non-text color contrast issues within CSS.

## Form controls

**Form controls should be clearly perceivable, and their current state easy to identify**. This may seem like an obvious statement, but it is not so obvious sometimes.

With current development and design trends, the creation of custom components, and new user flows definitions, sometimes the color contrast is forgotten.

Let's take [neumorphism](https://medium.com/@artofofiare/neumorphism-the-right-way-a-2020-design-trend-386e6a09040a) for example. It looks really cool, but it could become an accessibility nightmare if the intensity, blur, and size of the shadows don't create enough contrast for users to identify the component edges. 

<figure>
![Screenshot from dribble with neumorphic elements](https://dev-to-uploads.s3.amazonaws.com/i/tidsctatef8mse1d1wco.png)
<figcaption>Neumorphic UI/UX elements by <a href="https://dribbble.com/shots/9527558-Freebie-Neumorphic-UX-UI-Elements">Emy Lascan</a></figcaption>
</figure>

[WCAG 2.1 specifies that the indicator of an input must meet a 3:1 contrast ratio](https://www.w3.org/WAI/WCAG21/Understanding/non-text-contrast.html#active-user-interface-component-examples) (which is interesting because the default value in most browsers doesn't follow that spec).

There are more instances of insufficient contrast that needs to be addressed. For example, custom radio buttons and checkboxes should have enough contrast between the selected and unselected state. Even when the contrast ratio with the border may be fine, if a user with visual disabilities have trouble differentiating the background color and the selected color, then we are in trouble:

<figure>
![Examples of inaccessible looking radio buttons and checkboxes](https://dev-to-uploads.s3.amazonaws.com/i/ctcch9gs2qea3b0lx6ww.png)
<figcaption>These selected/checked status do not meet accessible contrast ratios</figcaption>
</figure>

This applies to more than just the _classic_ form components, there are many others like toggle buttons, rating systems, alert messages, toasts, loaders... Every component needs to have enough contrast to be able to differentiate it and know their status.

To do this, use the color contrast checkers from the previous article, or try different techniques:

- Ensure enough contrast
- Add borders to differentiate borders
- Use icons to emphasize the differences

<figure>
![Toggle buttons](https://dev-to-uploads.s3.amazonaws.com/i/pvx3xpo174ebemk1ry0e.png)
<figcaption>There are different options to provide enough contrast</figcaption>
</figure>

As described above, a great deal of the form components accessibility depends on the colors, borders, backgrounds... and all of that translates directly into CSS.

## Inline SVGs and currentColor

A common mistake that can be found in many sites is the use of icons that don't have enough contrast... or more specifically, they have enough contrast only in some states of the element that contains them.

Using inline SVGs as icons can take care of that problem because they can be styled with CSS by setting SVG-specific properties (like `stroke` or `fill`). And the [`currentColor` keyword](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#currentColor) can be handy to manage all the states of an interactive element without getting into messy code.

<figure>
![Example of a button with two different styles, in one the icon is not visible and in the other it isn't](https://dev-to-uploads.s3.amazonaws.com/i/cyw1r02fqwli7xtvr2dn.png)
<figcaption>Extreme example of <code>currentColor</code> improving user experience and code maintainability</figcaption>
</figure>

`currentColor` represents the value of the current `color` property (or its inherited value if it's not set), and will ensure that the inline SVG icons have the same color as the text. If we make the [text have enough contrast](https://dev.to/alvaromontoro/color-contrast-text-3l29), then the icon will have enough contrast automatically.

## Graphs and Charts

Although charts and graphs have been the domain of JavaScript for a long time, it is possible to display information in a chart form just using CSS (e.g. with <code>conic-gradient</code>).

It is not the best option at the moment, but we don't know where CSS can take us. If you do a graph/chart in CSS, make sure that the colors have enough contrast with the background and with the colors surrounding them, so they can be easily distinguishable.

{% codepen https://codepen.io/alvaromontoro/pen/LYGZMaO %}
<figcaption>Mouse over this pie chart to see it in grayscale</figcaption>


More about this on the next post...
 
---

**Color contrast is not exclusively for text: icons, form controls, images, and other web elements, must have enough contrast to be visible for everyone.**