---
title: Color
description: Ensure consistent use of color and readable contrast with Web Awesome's color properties.
---

<style>
  td { vertical-align: middle; }

  .color-name {
    font-weight: var(--wa-font-weight-semibold);
    margin-block-end: var(--wa-space-2xs);
  }
  ul.color-group {
    list-style: none;
    margin: 0;
    padding: 0;
  }
  .color-group {
    align-items: start;
    display: flex;
    flex-wrap: nowrap;
    gap: 0.25em;
  }
  .color-group + * {
    margin-block-start: var(--wa-space-xl);
  }
  .color-preview {
    flex: 1 1 auto;
  }
  .swatch {
    border-color: transparent;
  }
  .color-mix-example {
    background-image:
      linear-gradient(to right,
      color-mix(in oklab, transparent, var(--mix-color)) 25%,
      color-mix(in oklab, var(--wa-color-brand-fill-loud), var(--mix-color)) 25%,
      color-mix(in oklab, var(--wa-color-brand-fill-loud), var(--mix-color)) 75%,
      var(--wa-color-brand-fill-loud) 75%,
      var(--wa-color-brand-fill-loud))
    ;
    border: none;
    color: var(--wa-color-brand-on-loud);
    text-align: center;
  }
</style>

Web Awesome's color system is made up of CSS custom properties to help with consistent color use throughout your project.

Color is organized by three main categories:

- [Literal colors](/#literal-colors) that give familiar names to your starting [color palette](/docs/palettes/)
- [Foundational colors](/#foundational-colors) that lay the groundwork for your theme
- [Semantic colors](/#semantic-colors) that draw attention and convey meaning


## Literal Colors

Literal colors are defined by your theme's [color palette](/docs/palettes/) and are the lowest level color tokens in your theme. Each token is identified by a name, like red or gray, and a number based on the color's lightness. On this scale, 100 is equal to pure white and 0 is equal to pure black.

You can use these numbers to ensure accessible color contrast per [WCAG 2.1 success criteria](https://www.w3.org/TR/WCAG21/#contrast-minimum):

- A difference of 40 ensures a minimum 3:1 contrast ratio, suitable for large text and icons (AA)
- A difference of 50 ensures a minimum 4.5:1 contrast ratio, suitable for normal text (AA) and large text (AAA)
- A difference of 60 ensures a minimum 7:1 contrast ratio, suitable for all text (AAA)

Each Web Awesome palette defines seven literal colors each with 11 lightness values using the format `--wa-color-{hue}-{tint}`.

{% for hue in hues -%}
<div class="color-name">{{ hue | capitalize }}</div>
<ul class="color-group">
  {% for tint in ["95", "90", "80", "70", "60", "50", "40", "30", "20", "10", "05"] -%}
    <li class="color-preview">
      <div class="color swatch" style="background-color: var(--wa-color-{{ hue }}-{{ tint }})">
        <wa-copy-button value="--wa-color-{{ hue }}-{{ tint }}" copy-label="--wa-color-{{ hue }}-{{ tint }}"></wa-copy-button>
      </div>
      <small>{{ tint }}</small>
    </li>
  {%- endfor %}
</ul>
{%- endfor %}

## Foundational Colors

Foundational colors lay the groundwork for the content and structure of your project. These colors are named according to their role in your theme.

### Surfaces

Surfaces are background layers that other content rests on. Surface colors help convey hierarchy through a sense of elevation, where `--wa-color-surface-raised` is the closest to the user (e.g., dialogs and popup menus) and `--wa-color-surface-lowered` is the farthest away (e.g., wells).

| Custom Property               | Preview                                                                                                                         |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `--wa-color-surface-raised`   | <div class="swatch" style="background-color: var(--wa-color-surface-raised); box-shadow:var(--wa-shadow-s)"></div>              |
| `--wa-color-surface-default`  | <div class="swatch" style="background-color: var(--wa-color-surface-default)"></div>                                            |
| `--wa-color-surface-lowered`  | <div class="swatch" style="background-color: var(--wa-color-surface-lowered); box-shadow: inset var(--wa-shadow-s)"></div>      |
| `--wa-color-surface-border`   | <div class="swatch" style="border-color: var(--wa-color-surface-border)"></div>                                                 |

### Text

Text colors are used for standard text elements. We recommend a minimum 4.5:1 contrast ratio between text colors and surface colors.

| Custom Property          | Preview                                                    |
| ------------------------ | ---------------------------------------------------------- |
| `--wa-color-text-normal` | <div class="swatch" value="--wa-color-text-normal" style="color: var(--wa-color-text-normal); display: inline-block;">AaBb</div> |
| `--wa-color-text-quiet`  | <div class="swatch" value="--wa-color-text-normal" style="color: var(--wa-color-text-quiet); display: inline-block;">AaBb</div>  |
| `--wa-color-text-link`   | <div class="swatch" value="--wa-color-text-normal" style="color: var(--wa-color-text-link); display: inline-block;">AaBb</div>   |

### Overlays

Overlays provide a backdrop to isolate content, often allowing background context to show through.

| Custom Property             | Preview                                                                             |
| --------------------------- | ----------------------------------------------------------------------------------- |
| `--wa-color-overlay-modal`  | <div class="swatch" style="background-color: var(--wa-color-overlay-modal)"></div>  |
| `--wa-color-overlay-inline` | <div class="swatch" style="background-color: var(--wa-color-overlay-inline)"></div> |

### Shadow

Web Awesome uses a single color for all shadows.
This is used alongside other [shadow tokens](/docs/tokens/shadows) to construct your theme's shadows.

| Custom Property     | Preview                                                                     |
| ------------------- | --------------------------------------------------------------------------- |
| `--wa-color-shadow` | <div class="swatch" style="background-color: var(--wa-color-shadow)"></div> |

### Interactions

#### Focus

Web Awesome uses a single focus color for predictable keyboard navigation. This is used alongside other [focus tokens](/docs/tokens/focus) to construct `--wa-focus-ring`. We recommend a minimum 3:1 contrast ratio against surface colors and background colors wherever possible.

| Custom Property    | Preview                                                                                                                 |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------- |
| `--wa-color-focus` | <div class="swatch" value="--wa-color-focus" style="outline: var(--wa-focus-ring-style) var(--wa-focus-ring-width) var(--wa-color-focus)"></div> |

#### Hover and Active

Web Awesome leverages `color-mix()` to achieve consistent hover and active states across components without the need for untold numbers of handpicked colors. Through `color-mix()`, these custom properties contextually generate hover and active colors based on the color of the component.

| Custom Property         | Preview                                                                                                          |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `--wa-color-mix-hover`  | <div class="swatch color-mix-example" value="--wa-color-mix-hover" style="--mix-color: var(--wa-color-mix-hover)"><small>mixed</small></div>  |
| `--wa-color-mix-active` | <div class="swatch color-mix-example" value="--wa-color-mix-active" style="--mix-color: var(--wa-color-mix-active)"><small>mixed</small></div> |


## Semantic Colors

Semantic colors reinforce a specific message, intended usage, or expected results through familiar, meaningful hues. Each color is identified by its semantic group, role, and attention using the format `--wa-color-{group}-{role}-{attention}`. There are five groups of semantic colors:
- **Brand** to emphasize your brand color
- **Success** for validity or confirmation
- **Neutral** for ordinary or inactive content
- **Warning** for caution or uncertainty
- **Danger** for errors or risk

Each group defines colors for specific roles so that colors can be easily assembled with predictable results and readable contrast. There are three roles:
- **Fill** for background colors or areas larger than a few pixels
- **Border** for borders, dividers, and other stroke-width elements
- **On** for content displayed on a fill (e.g., pair `--wa-color-danger-on-loud` with `--wa-color-danger-fill-loud`)

Finally, each color is named according to how much attention it draws. Here, we use noise as an analogy: a loud noise draws more attention than a quiet one. There are three levels of attention:
- **Quiet** draws the least attention
- **Normal** draws some attention
- **Loud** draws the most attention

{% set variants = ['brand', 'success', 'neutral', 'warning', 'danger'] %}
<table>
  <thead>
    <tr>
      <th>Custom Property</th>
      {% for variant in variants -%}
        <th><code>{{ variant }}</code></th>
      {%- endfor %}
    </tr>
  </thead>
  {% for type in ['fill', 'border', 'on'] -%}
    {% for attention in ['quiet', 'normal', 'loud'] -%}
      <tr>
        <td><code>--wa-color-*-{{ type }}-{{ attention }}</code></td>
        {% for variant in variants -%}
          <td>
            {%- if type == 'border' -%}
            <div class="swatch" style="border-color: var(--wa-color-{{ variant }}-{{ type }}-{{ attention }})"></div>
            {%- else -%}
            <div class="swatch" style="background-color: var(--wa-color-{{ variant }}-fill-{{ attention }}); color: var(--wa-color-{{ variant }}-on-{{ attention }})">{{ 'AaBb' if type == 'on' }}</div>
            {%- endif %}
          </td>
        {%- endfor %}
      </tr>
    {%- endfor %}
    {%- endfor %}
</table>
