Search code examples
javascriptcsscolorsgetcomputedstylecssom

Is color format specified in the spec for getComputedStyle?


I'm parsing a color string returned by getComputedStyle to get R, G, B, and A values from it.

So far (in Chrome and Firefox), color values always seem to come back in rgb or rgba format which is easy to parse:

const [, r, g, b, a] = str.replace(/\s/g, "").match(/rgba?\((\d+(?:\.\d+)?),(\d+(?:\.\d+)?),(\d+(?:\.\d+)?)(?:,(\d+(?:\.\d+)?))?\)/i);

I cannot, however, find any promise about color format in any of the specs for getComputedStyle listed on its MDN page.

Is there any guarantee of color format from getComputedStyle? Or is it entirely up to browser implementation?

I'd prefer not to have to check for HEX and HSLA values (and really whatever else is possible - I'm not entirely sure).

A quick snippet of code for testing color values in your console:

console.log((str => {
    const div = document.createElement("div");
    div.style.backgroundColor = str;
    document.body.append(div);
    return getComputedStyle(div).backgroundColor;
})("magenta"));


Solution

  • CSSOM does not state this directly, but instead references css-color-4:

    To serialize a CSS component value depends on the component, as follows:

    <color>
    If <color> is a component of a resolved value, see CSS Color 4 §4.6 Resolving <color> Values.

    If <color> is a component of a computed value, see CSS Color 4 §4.7 Serializing <color> Values.

    For the purposes of getComputedStyle(), both of the above lines mean the same thing. Specifically, section 4.7.2 covers the majority of commonly used formats:

    4.7.2. Serializing sRGB values

    The serialized form of the following sRGB values:

    • hex colors
    • rgb() and rgba() values
    • hsl() and hsla() values
    • hwb() values
    • named colors

    is derived from the computed value and thus, uses either the rgb() or rgba() form (depending on whether the alpha is exactly 1, or not), with lowercase letters for the function name.

    Section 4.7.6 covers system colors (computes to lowercase), transparent (computes to rgba(0, 0, 0, 0)) and currentColor (computes to lowercase currentcolor).

    As css-color-4 introduces several new ways to specify colors, other sections exist for other formats such as §4.7.3 for LCH values, §4.7.4 for the color() function, and more.

    This means that color values from getComputedStyle() are guaranteed to be in either rgb() or rgba() format, depending on the alpha value, only when the specified values are in any of the formats in §4.7.2. But §4.7.2 and §4.7.6 cover the vast majority of use cases in everyday CSS, so they can still be relied on. Considering the other, exotic formats aren't really supported anywhere yet, it's probably not worth testing for them until they enjoy any sort of mainstream use.