Motivation
My main aim is to establish CSS as the primary source for color definitions. I am hesitant to duplicate these values into JavaScript variables as it would require updating code in two separate locations if any changes were made to a specific color.
Within my CSS file, I have a comprehensive list of colors stored as CSS Variables (also known as CSS Property Values).
/* variables.css */
:root {
--indicator---red: rgba(255, 46, 46, 1);
--indicator---red--dark: rgba(201, 37, 37, 1);
--indicator---green: rgba(71, 205, 38, 1);
--indicator---green--dark: rgba(57, 172, 28, 1);
--indicator---amber: rgba(244, 182, 60, 1);
--indicator---amber--dark: rgba(208, 156, 56, 1);
}
Currently, I am using React in my project. I have a functional component called TrafficLight
that needs to directly access these colors from my CSS Variables. I intend to accomplish the following:
// TrafficLight.js
function TrafficLight({status}) {
switch (status) {
case "GREEN":
color = getComputedStyle(document.documentElement).getPropertyValue("--indicator-green")
break;
case "YELLOW":
color = getComputedStyle(document.documentElement).getPropertyValue("--indicator-amber")
break;
case "RED":
color = getComputedStyle(document.documentElement).getPropertyValue("--indicator-red");
break;
}
return (<div className="circle" style={{backgroundColor: color}} />);
}
Issue
The challenge I'm encountering is that React is unable to access the CSS Variables defined within :root
since
CSSStyleDeclaration.getPropertyValue()
consistently returns an empty string.
Attempted Solutions
- Experimenting with using vanilla JavaScript to access the DOM, however, since React operates using a virtual DOM, this method fails to recognize the
:root
selector:
getComputedStyle(document.documentElement).getPropertyValue('--my-var')
getComputedStyle(document.body).getPropertyValue('--my-var')
window.getComputedStyle(document.documentElement).getPropertyValue('--my-var')
Exploring the option of waiting for the component to mount and conducting the lookups within a
useEffect()
block.Trying to avoid utilizing
useRef
and passing the:root
reference down to my component through prop-drilling, given the structure of my project:
<App>
<Parent1>
<Parent2>
<Parent3>
... // Several components deep
<TrafficLight>