Keeping up with Kibana: This week in Kibana for April 26, 2018

With the release of 6.0, Kibana took aim at providing a more inclusive, accessible design than in our previous versions. For those lost in terminology, accessible design refers to building a user interface that is usable by people of all backgrounds and abilities. It’s one of the core principles of the new Elastic UI Framework that powers Kibana’s design. In practice, meeting that goal means focusing on four main interface challenges.

Providing high-contrast, readable text

Providing color-blind safe UIs and visualizations

Making sure our UI is navigable by a keyboard

Using ARIA labels and semantic HTML to make the UI available through screen readers

In this post, we’ll discuss the first two points and how the Kibana design team meets these goals through tooling. It might sound fairly easy to do, or even boring, but by the end you’ll see just how much time (and math!) goes into calculating “high-contrast” and “color-blind safe” designs. As something to look forward to, I promise to also end the mystery of why Kibana is no longer pink!

Defining some rules

First, it’s important to note that when designing with accessibility in mind, the WCAG provides some pretty great resources and rulesets. Their documentation can get pretty dense, but when making decisions around accessibility, your first stop should always be to read the WCAG guidelines.

Two important guidelines to memorize are 1.4.1 and 1.4.3:

1.4.3 states that color alone can not be the only way to convey visual information

To understand what this means, let’s start with color first. Design is mostly the application of recognizable, repeatable patterns. A pattern you’ve probably run into, and which designers commonly employ, is that green is good, yellow is a warning, and red is danger. You see this pattern every time you drive a car. But what if you are one of the 1 in 12 men (it’s less common in women at 1 in 200) who are affected by Protanopia and have trouble distinguishing red from green?

Solving this problem is typically pretty easy. Rather than assuming people can see the difference in colors, we can be more explicit and use iconography and text as another way to convey our message. However, for more visually expressive elements, such as Kibana’s charting libraries, this is much harder to achieve. The legend on an area chart might define the purpose of a certain color, but that doesn’t do much good when you can’t tell the difference between the colors. In this situation, coming up with a color-safe palette (described in the next section) becomes more essential.

It all starts with the design

The Kibana design team uses Sketch to prototype our visual designs. It’s usually the first place we start laying out the interfaces that make up Kibana. Even this early in the process we want to think about accessibility and color. Luckily, we have some community tools to help us out.

In particular, we love Stark, a Sketch plugin and overlay that let’s us simulate various forms of vision impairment and color blindness. We use Stark often when making designs, and more importantly, picking colors for our palettes. Here’s an example of how it works:

Using Stark we came up with the colors in the Elastic UI framework. I’d love to say that there was a a super scientific way we formulated these colors, but it was actually quite organic. We started with our branding colors as a seed, and then added and tweaked more colors. In the end, we had a full palette of 10 colorblind safe colors.

The ability to distinguish each color individually became harder and harder with each new color we added. That’s because the new color had to be visible against all the previous ones. Essentially, large palettes can never be colorblind proof and aiming for ten distinct colors is likely as far as you can take it. If you do need more colors, remember that luminosity (the perceived brightness) rather than hue (the actual color itself) is the better thing to adjust.

In code, color is math

Our Sketch mocks are just a rough idea of what our designs can be. They deal more with layout than implementation. It’s only when these designs translate to code that we really begin to understand how color works.

We build the Elastic UI Framework with Sass, which gives us a lot of control to variabilize and manipulate our colors. As a pretty hard rule of EUI, the only hex colors you’ll see in our code are defined as variables. Any other color must be derived, through color functions beyond that original set.

That’s all good for dealing with individual colors and likely not too much different from what you’ve seen in other frameworks. But what happens when we use one color as a background and another as a foreground? How do we know if they work as far as accessibility goes? More interestingly, how can we make these colors always pass a contrast against each other?

Here we really leaned into Sass and made some functions that can do the following.

Calculate luminance

Luminance is the perceived brightness of a color. Unlike true brightness, it has less to do with the amount of white or black in a color, but how different colors like yellow look brighter than darker colors like purple. We use luminance to calculate true contrast as defined by the WCAG.

Note that calculating luminance is no joke from a math standpoint and there are a lot of bad calculations floating around on Google. In fact, the below function actually utilizes some additional math functions that Sass doesn't have access to. Rather than make this post overly long you can grab them over here to make this function work. For now though I just want to show that we need to calculate luminance to properly calculate contrast.

Calculate contrast ratio

Contrast is a ratio that compares the luminance of one color against the luminance of another. A higher ratio means a higher contrast. In practice, you should always pair a high luminance color (like bright yellow) with a low luminance color (like dark blue). The hue of the color doesn’t matter--only luminance matters when making these calculations. As mentioned before and by WCAG 4.5 is the magic number we're looking for to make our text accessible.

Force a given color to pass a contrast test

We know we want to pass a 4.5:1 contrast check for accessibility, but sometimes this is extremely hard when working with certain color hues. For example, yellow is very hard to render on white. This function allows us to pass a foreground color (like yellow) and a background color (like white) and adjust the foreground color darker until the contrast is high enough to pass. What we end up with is a darker shade of yellow (similar to mustard) that reads close to the intention of our original color but now passes an accessibility check.

Testing and awareness

The functions and mixins we provide are pretty automatic, but even then you must remember to use them. The engineering team at Elastic is large and they’re more likely to pull from the original palettes rather than use the Sass mixins. Because of this, we provide documentation and testing that illustrates our color contrasts.

The above page takes the Elastic UI color palette, compares the colors in a grid, and gives a WCAG rating for each combination. This gives our engineers confidence in knowing which levels of gray to use for text, and which for purely decorative purposes.

Beyond that, we also use Chrome extensions to test contrast values in the browsers. Although these tools are by no means perfect, they do send up smoke on systems we need to keep an eye on.

So why not pink?

I promised an end to the mystery on why Kibana 6 stopped being so pink. Elastic’s brand of pink is a color that sits in between luminance extremes at 0.271. This makes it equally hard to pass a contrast check using either white or black foreground text. Instead we choose one of the brand colors (blue) that has a better range of luminosity. Blue can be recognizable with high and low luminance no matter how we shade it, and looks good with either light or dark text. Pink on the other hand requires a high luminance to be recognizable as pink and needs to shade darker (into a plum) to pass a contrast check against white. Put bluntly: blue is much easier to work with as far as accessibility is concerned.