Search code examples
javascriptcsscolors

How can I get final hex color in Javascript from a relative CSS color string?


Let's say I have a CSS like that, which uses CSS Relative Colors syntax:

.my-element {
  color: rgb(from #aabbcc calc(r + 30) g calc(b - 30) / 80%);
}

(Updated to the correct syntax according to the comments below)

(in real life, this example would use CSS variables which I know how to substitute with actual values, so I simplified it).

In CSS it calculates a color with increased red and decreased blue channels, and with 80% alpha-channel.

I need to get that color and further manipulate it in my JS. Tried using getComputedStyle - it doesn't help, just returns the initial string representation of the color.

So, is there a way to get that final color in JS? Any built-in solution or a library?


Solution

  • As mentioned by @temani-afif, the correct syntax is:

    .my-element {
        color: rgb(from #aaaaaa calc(r + 30) g calc(b - 30) / 80%);
    }
    

    Then, to get the computed color, you can use getComputedStyle (I changed #aabbcc to #aaaaaa for better representation):

    const element = document.querySelector('.my-element');
    const computedStyle = getComputedStyle(element);
    const color = computedStyle.color;
    console.log(color);
    .my-element {
      color: rgb(from #aaaaaa calc(r + 30) g calc(b - 30) / 80%);
    }
    <div class="my-element">Some Text</div>

    Additionally, if you want to convert that to rgba:

    function srgbToRgb(srgb) {
      const match = srgb.match(/^color\(srgb\s+(.+?)\s+(.+?)\s+(.+?)\s+\/\s+(.+?)\)$/);
      if (!match) {
        throw new Error('Invalid srgb color');
      }
      const r = Math.round(parseFloat(match[1]) * 255);
      const g = Math.round(parseFloat(match[2]) * 255);
      const b = Math.round(parseFloat(match[3]) * 255);
      const a = parseFloat(match[4]);
      return `rgba(${r}, ${g}, ${b}, ${a})`;
    }
    
    const element = document.querySelector('.my-element');
    const computedStyle = getComputedStyle(element);
    const color = computedStyle.color;
    console.log(srgbToRgb(color));
    .my-element {
      color: rgb(from #aaaaaa calc(r + 30) g calc(b - 30) / 80%);
    }
    <div class="my-element">Some Text</div>