A11Y Color Contrast, Button Triads, and the new Pivotal UI Color Palette
Recently, I joined the Pivotal Apps Manager team with one express purpose: make it more accessible. I chose this team because its development team also builds and maintains the Pivotal UI style guide.
By improving the accessibility of AppsMan, as it is so lovingly called, I hope to abstract many of the updated components and bring them back into the Pivotal UI, enabling the 14 (or so) teams who use it to automatically become just a little bit more accessible.
This will also allow me to stress-test many of the components in a real use-case before setting it up as a universal component.
Of course, accessible components can only get you so far, but it’s a great start, and part of my time will include advocacy and teaching to help more teams work inclusively from the start.
Updating The Existing Palette
The first thing I could do outside of Apps Manager, however, is to help update the color palette in the Pivotal UI style guide to have more accessible colors, in a more understandable way. I joined a group of two awesome PCF designers, Christine Yeh and Shirley Wang, who have been contributing their off-hours to improve the style guide for everyone who uses it.
We began by taking stock of the existing color palette, which had a lot of colors (around 57!), with many similar options without a lot of guidance on what to use, when, and furthermore, why!
One of the first issues we discovered was that in this palette, the onus was on our users, the developers and designers using Pivotal UI.
They not only had to know and care about accessibility contrast needs, but also to go through and check every usage themselves, one by one, in our contrast checker — which was already somewhat hidden, and not included in the same place as the colors themselves. We wanted to both cut down the number of colors and make sure that the most common color combinations people were using were AA contrast-accessible.
Some great work had already started; the team had done an audit of the current color usage across many of Pivotal’s user interfaces and noted outliers, guidelines for use, and frequency of use. Using this information, we identified the most common combinations that needed to be checked for contrast.
We started putting colors into families by shade and usage, adjusting them by contrast need and de-muddying some of the colors; this entailed adding back in some needed saturation to give them more life and make them feel more contemporary with current UI trends (as seen in the Google material design system, Invision, and across Dribbble).
By the end of this audit, we cut the palette down to 4 shades of gray, 4 shades of blue, 3 shades of teal, 3 shades of red, 3 shades of green, and 2 shades of yellow.
Because yellow is a distinctly difficult color to use on white or light backgrounds, we put aside trying to make a “yellow” that was dark enough to be contrast-accessible. Instead, we decided to assign the light variant to be used as a background color and the brighter “decorative” variant for use in elements (such as illustrations or non-interactive icons) that had purely aesthetic use in an app or product.
This opens the door for the future addition of other possible “decorative-only” colors (Orange? Purple? Fuchsia??!) for illustrative usage in the palette, though we’re keeping it lean for now. ;)
Making Sense of What Colors to Use, When
Already, curating the 57-color palette to 20 means that it’d be a lot easier to choose what colors to use, and when to use them. But we also wanted to integrate some naming rules for the colors, so designers and developers quickly grok what combinations are accessible. We chose a simple naming system:
- Colors appended with accent (i.e., “accent-blue”) would be AA large-text contrast-accessible on white.
- Colors appended with dark and light (i.e., “dark-blue” used on a “light-blue” background) would be contrast-accessible with each other.
- Colors that consisted of their name alone (i.e., “blue”) would be AA contrast-accessible with both white and black.
We also used the awesome Cloudflare.design color tool to generate all possible accessible color combos, so designers would have an immediate visual indication of acceptable combinations, as well as potential inspiration.
Making it Real
Now that we had a new palette, we came to the most difficult, and important part: how can we help the existing users of Pivotal UI, spanning several individual teams across Pivotal Cloud Foundry, migrate over with minimal pain?
To start out, we mapped which new colors to switch to if using X old color — so if previously you were using brand-4, brand-5, or brand-6, say, now you’d use teal.
Another note on our naming: there are a lot of opinions based on what to name your colors, many which recommend avoiding the actual color name in favor of “dark” or “primary” or “brand.” We opted for the simpler, more straight-forward route, in this case, where the colors are named for their position in the grouping of shades.
But the question nagged: how can we guarantee accessibility when we don’t have a complete idea of how this would work in the wild?
Would our substitutions of black be far too strange? How can we enable the color palette switchover without scaring people off with the prospect of having to redesign their entire apps?
Buttons Are Hard!
To start experimenting with the colors applied to their real use, I started with buttons. Buttons are notorious for needing many states, all of which need to be accessible. I started with the most common buttons used in the app: our primary blue, an alternative teal, our “this is a dangerous button” red, and an unassuming gray.
I struggled in particular with the buttons when I started looking into how their states should work on a dark UI:
Between these failed experiments and my subsequent attempts applying it to AppsMan, I came to an epiphany: in modern UI design, we are rarely if ever using colors on pure black or white.
In fact, across the Pivotal apps, people tended to only use white, light gray, and dark gray as backgrounds. Since I had optimized the “default” colors to be contrast-accessible on both pure white and pure black, I often found myself to jumping down the shade scale to make sure all my colors were accessible, which in turn hurt both the visual cohesion and the attention-grabbing ability of my interactive elements.
In modern UI design, we are rarely if ever using colors on pure black or white.
My call to action button, intended to be the main action on any page, was receding into the background and looking like a totally different element from the interactive elements on white:
So what now? The first option I considered was to add back in some more shades, which would allow designers to make smaller jumps down the scale as needed, and avoid that dark navy. But this approach risked undermining the whole power of our new system. Introducing extra shades without guidance could confuse or muddle future users, and make it easier to confuse things. People could start to ask, well, why are we changing things at all?
I could also try to be more prescriptive about our UI patterns, insisting that we adjust our existing designs to ensure that all interactive elements, including our primary action buttons, lived on white (or black, for dark UIs).
But of course, this came with its own pitfalls: for one, being inflexible did not bode well for getting more teams to adopt our style guide, its purported accessibility gains notwithstanding. It would also mean a much larger lift for those who still wanted to adopt our new guidelines.
Finally, forcing the use of predominantly higher-contrast colors like pure black and pure white could introduce problems of glare and eye-strain, something we definitely didn’t want to induce in our users: app developers who were coming from their highly-customizable, individualized code editors.
Enter The Button Triads
So I came to what is not a perfect solution but could work as something of a compromise: Button Triads.
The concept of the button triad is to include trios of colors to be used exclusively for buttons. These triads are designed as a cohesive unit of colors that will be AA contrast-accessible across both light and dark segments of our interfaces.
The triad for each color family includes the single-named color from the main palette and two sub-colors, one for the button on a light UI and one for the button on a dark UI.
The color names would be appended with something like blue_btn — onLite and blue_btn — onDark so it is clear when they should be used, and they will live outside the main palette, branching off their single-named color.
I also realized these colors could be specifically tailored to work with our Pivotal palette, cohesive with itself. I created our button triads to exist within our color family, with the exact light-gray and dark-gray shades used as our most common background colors.
Button Triads IRL — Feedback needed!
Will it work? My main concern, also raised by some of the developers on my team, is the visual similarity between the “blue” and the “_btn — onLite” shades within the button triad colors.
We could take out the single-color options among the button colors — basically, remove the black-white AA-accessible blue, teal, red, and gray, leaving only the button pairs — but would that confuse the naming system overall, and cut out those options for non-button UI elements?
The next question is, how to ensure their best usage? I’m wrapping my brain around several questions based on this potential solution:
- Are the names in the code enough to signal to that you may be using the wrong color variant?
- Can we rely on ensuring our button components follow the correct usage?
- Is there a way for the code itself to detect its own background and adjust its shade accordingly? It may take some tricky coding (and not be necessarily worth it), but it may also be a cool project for a bored engineer looking for a side hustle (please let me know if you figure this out!)
What do you think? How would you approach this, if you were to use the new palette with the button triads? Any feedback would be greatly appreciated!