Background Color

Sets the background color of a component.

Valid values

  • Known color name: red, limegreen, transparent
  • Hex color: #a5a5a5, #777, #00ff0033
  • RGBA color: rgba(23, 16, 168, 0.3), rgb(23 16 168 / 30%)
  • HSL color: hsl(152, 37%, 59%), hsla(152 37% 59% / 0.75), hsl(152 37 59)
  • OKLCh color: oklch(63.7% 0.237 25.331), oklch(0.5 0.2 30deg / 50%)
  • OKLab color: oklab(0.5 0.1 -0.1)
  • LCh color: lch(54.29% 106.84 40.86), lch(70 30 0.5turn)
  • Lab color: lab(50 40 -30), lab(50 40 -30 / 50%)
  • Mixed color: color-mix(in oklab, red 30%, blue) — see below
  • Relative color: rgb(from var(--brand) r g b / 50%) — see below
  • CSS keywords: inherit

Every component of these four is a number or a percentage, and one written as none is 0. What 100% means differs by function, because each space has its own ranges:

FunctionLightnessChroma, or the a/b axes
oklch()010.4
oklab()010.4
lch()0100150
lab()0100125

So oklch(0.637 …) and oklch(63.7% …) are the same lightness, while in lch() both 54.29 and 54.29% mean 54.29. In hsl() and hsv() saturation and lightness run 0100, so the % may be left off: hsl(152 37 59) is hsl(152 37% 59%). Hue takes any angle unit and wraps, so 512deg is 152deg. A component outside its range is clamped rather than making the declaration invalid, so rgb(300 0 0) is red and hsl(0 150 50) is a saturation of 100%.

color-mix() interpolates two colors in srgb, srgb-linear, hsl, lab, lch, oklab or oklch. Each percentage is optional and may be written on either side of its color; giving one implies the other, and a pair summing to under 100% scales the result’s alpha by that sum. Alpha is premultiplied, so mixing with transparent fades the color instead of darkening it. In the polar spaces — hsl, lch and oklch — the hue may carry shorter hue, longer hue, increasing hue or decreasing hue, defaulting to shorter.

Relative colors

Every color function above also takes a from <color> origin, which is CSS Color 5’s relative color syntax. The origin is converted into the function’s own space, and each of its channels becomes a keyword the channel slots can use — on its own, or inside calc():

.button {
  /* A hover shade of whatever the button's own color turns out to be */
  background-color: oklch(from var(--brand) calc(l * 0.8) c h);
  /* The same color at half opacity, without repeating it */
  border-color: rgb(from var(--brand) r g b / 50%);
  /* The complement */
  outline-color: hsl(from var(--brand) calc(h + 180) s l);
}

The keywords are r g b in rgb(), h s l in hsl(), h s v in hsv(), l a b in lab() and oklab(), l c h in lch() and oklch(), and alpha in all of them. Any of them may appear in any slot, so rgb(from red b g r) is blue. Each is worth what the slot would make of that number, so r is 0255, hsl()’s s is 0100, oklch()’s l is 01, a hue is degrees and alpha is 01 — the ranges listed above.

An omitted alpha is the origin’s own rather than 1, so rgb(from <color> r g b) is that color unchanged. The origin may be any color, including currentColor, a var(), a color-mix() or another relative color; one that is not a color makes the declaration invalid. Only the space-separated form is relative — rgb(from red, r, g, b) is not.

A color outside the sRGB gamut is clamped per channel, which shifts the hue of a very saturated color. Naming an interpolation space that is not in the list above, such as display-p3 or rec2020, makes the declaration invalid rather than silently mixing in a different space.

.test {
  width: 240px;
  height: 160px;
  margin: 40px auto;
  border: 1px solid black;
  animation: backgroundColorAnim 8s infinite;
}

@keyframes backgroundColorAnim {
  0% {
    background-color: crimson;
  }

  25% {
    background-color: #a5a5a5;
  }

  50% {
    background-color: rgba(10, 10, 235, 0.4);
  }

  75% {
    background-color: #00ff0033;
  }

  100% {
    background-color: crimson;
  }
}