Skip to content

Hey, I Think We Need a Button – Part 2: State and Context

06/01/2025

What does it take to create a design system? In this blog series I’ll go over intricacies of designing a single UI-component for a made-up design system. It’s a deep dive into what and why, to give you an overall introduction to the topic.

In the previous part of this series we dove into design tokens by breaking a button component into its core elements—you might want to read it first as we expand on the ideas presented there. Now, this time we’ll figure out how our button should behave in different situations and contexts. And touch the topic of accessibility while we’re at it.

Fig. 1. Let me introduce you to the star of the evening: it’s a button!

Interaction states

Whenever the user interacts with the button, the interaction should be reflected in the appearance of the button. Let’s start by adding some interaction states to our button. In Fig. 2 you can see our button in hover, press, and focus states.

Fig. 2. Interaction states. Note that some interaction states are specific to an input method: hover doesn’t apply to touch interfaces.

Looks good! Now the user gets feedback when hovering or pressing the button and—even more importantly—it’s accessible to keyboard users as there’s now a keyboard focus indicator as well. And talking of accessibility, any guesses why the button gets darker instead of lighter for hover and press states, as shown in Fig. 3?

Fig. 3. Looks a bit nicer? Maybe, but buttons don’t exist to be looked at, they exist to enable users to accomplish tasks.

As the contrast between the button background and the text decreases, the text becomes harder to discern from the background. In fact, the contrast ratio in that hover state is below the absolute minimum accessibility standard. (WCAG 2.2 AA level: minimum contrast ratio of 4.5:1 for text size of 16 pixels.) In short, some significant percentage of users will have hard time reading the text when hovering the button.

Picking colors and color combinations systematically, using design tokens with a well thought out naming structure helps us stay within safe parameters. In this case our tokens could be named:

  • color-accent
  • color-accent-hover
  • color-accent-press
  • color-accent-foreground

Non-interaction states

There are two more states I want to mention before we move on to the next thing. In Fig. 4 we have two states for situations where the button can’t be interacted with: a generic disabled button and a button with loading indicator.

Fig. 4. WCAG specifically omits disabled controls from any contrast ratio requirements as the conventional appearance (low contrast gray-on-gray) is by definition inherently inaccessible to some portion of users.

Now is a good time to mention screen reader users. When a user navigates to the button on the left (Fig. 4) using a screen reader, they’ll hear something like “button, disabled, sample”. But what about the button on the right? Probably something like “button, disabled, loading”, though that is not explicitly apparent by just looking at the picture.

We can use accessibility annotations to document the intent in these kinds cases. So, we accompany the loading button with the following annotation:

  • Disabled: true
  • Label: “Loading”

Existence of such annotations on the design system level makes the requirements of the implementation clear to the developers and they can also act as reminders for the designers of things to keep in mind when designing the actual UIs.


Color modes

Many design systems are designed to work in both light and dark modes. So far we’ve only worked in light mode: our button works nicely on white background. But if we switch to dark mode, we also need to adjust the colors of our button. (Fig. 5)

Fig. 5. Same button, different context.

At this point we start to reap some of the rewards of our ground work with design tokens. To add a dark mode, all we have to do is to define a second set of values for all the color tokens we have (Fig. 6).

fig-6-1Fig. 6. A single token can have multiple values, depending on context.

Providing user a choice between light and dark mode is also an accessibility feature. There are medical conditions that can severely impair one’s ability to use bright UIs and the same is true for dark UIs. Providing this kind of option let’s the user pick the one that doesn’t cause issues for them, potentially turning an unusable experience to an enjoyable one.

Fig. 7. Interaction states in dark mode.

And there are even more ways to support user preferences. Example: some users might prefer high or low color contrast. Operating systems already let users to set contrast preferences and it’s up to individual applications and websites to support those preferences. For some examples, Apple systems offer “increase contrast” option while Android has recently added a three level contrast setting (default, medium, high) in addition to a separate high contrast text setting.

But let’s instead look into Windows High Contrast Mode. In Windows HCM, the color palette is reduced to just eight different colors. Each of these colors is assigned a specific purpose: background, regular text, links etc. And each of these eight colors is completely customizable by the user. So as a designer you’ll have very little idea of how the UI will look to a Windows HCM user. Your job is to make sure that each element is assigned the correct color and that as little as possible is lost in translation.

fig-8-1Fig. 8. Interaction states in Windows HCM. That’s half of the eight Windows HCM colors used here.

Making UIs work with windows HCM can be a daunting task: you can’t rely solely on the kind of token magic we did with light and dark modes because there’s just isn’t enough colors available to represent all the meaning and nuance present in our original color scheme. And that’s ok: if the user prefers Windows HCM, with how raw and outright hostile it might look to you, they probably have very good reasons to prefer it—reasons that outweigh the loss of meaning and nuance.

Responsiveness and writing direction

Screen size is another variable that we might want to make our components adapt to. Design choices that make sense on a small phone screen might not make so much sense on a large desktop monitor. Our button has quite generous side paddings to give it a clean and balanced look. But this kind of carefree use of space could lead us to trouble on smaller screens, especially if we want to show multiple buttons side by side.

fig-9-1Fig. 9. Responsive button sizing.

In Fig. 9, we now have two sizes for buttons, our original button for large screens and a new smaller one for small screens. But what do “large screen” and “small screen” mean, in exact terms? In the simplest case we have a separate app for mobile phones and desktop computers and there’s no confusion. But if we are targeting web or any other platform with varying screen sizes, we need a way to map our button sizes to the screen sizes. To do this, a design system should define a set of shared breakpoint tokens that turn abstract concepts like “small screen” to actual screen sizes, usually screen sizes in pixels.

But let’s not delve too deep into responsive design as that tangent is “a bit” too much to un-tangle in a single blog post. Instead, I want to mention one more category of context that might affect what we are doing with our button here: language. And specifically, languages that are read and written right-to-left like Arabic instead of left-to-right like English. In these languages the whole user interface is flipped so that right becomes left and left becomes right.

This doesn’t affect our button yet as the button is symmetrical. But later when we start adding icons next to the button text, we’ll have to adjust our language when talking about the different sides of the button, to prevent confusion. (We’ll use “leading” and “trailing” instead of “left” and “right”.)

In conclusion

This post has three takeaways:

  • Even a seemingly simple component like a button can manifest in many different ways depending on the context or the actions off the user.
  • Many accessibility concerns are tackled on a design system level. A design system can be used to promote accessibility aware approach to both UI design and technical implementation.
  • As we move toward more and more complex needs, our groundwork with design tokens and systemic thinking starts to pay dividends.

In the next part of this series, we’ll add a bunch of different variants to our button—and address the increasing need of a clear documentation that comes with them.