Stop duplicating constants between JS and CSS

Two techniques to prevent the repetition of constants in JS and then in CSS

Santiago Vilar
Level Up Coding

--

Photo by Pankaj Patel on Unsplash

We know that having more than one source of truth can only result in madness. But something I encountered in several front-end codebases is the repetition of style constants (colors, fonts, sizes) in CSS and in JS. We put the primary color in the CSS in a nice variable, but then we need it in our JS code (for whatever valid reason it is), so we go ahead and create a constant for it, because we’re not going to hardcode that value, oh no! But we’re still violating the DRY principle. Don’t repeat yourself.

So today I’m gonna present you with 2 techniques to either declare that variables in CSS and use them from JS, or viceversa.

JS => CSS

So you’re decided to use JavaScript as your source of truth. It’s OK, you have your reasons. For instance, you’re maybe loading these constants from a npm package, they’re exported as JS constants and you need to inject them into the CSS.

So first, you need to have a method of injecting CSS from your code. Here’s a function for that:

function addStyle(styleString) {
const style = document.createElement('style');
style.textContent = styleString;
document.head.append(style);
}

This function receives a parameter styleString, that will be the CSS we want to inject. The first line of the function creates a <style> element, the second one sets the content of that element to the styleString parameter, and the last one appends that element to the <head> portion of our HTML. That’s it.

Once you have that function, you can call it with the standard declaration of a CSS variable.

addStyle(`
:root {
--color-primary:
${primaryColor};
}
`
)

Great! So now you can access that variable from the CSS!

button {
background: var(--color-primary);
}

That’s it! Easy, right?

This method has one caveat, though. The CSS now depends on the JS being loaded and executed. Why is this important? Typically, the CSS is the first thing you load of a page, and the JS is the last. You may already have that issue, if you use CSS-in-JS for instance, but it’s good to keep it in mind.

Here’s a codepen with an example to play!

JS to CSS

CSS => JS

This is a handy way to access your CSS variables from the JavaScript code.

This method relies in the following code snippet:

function getCSSVariable(varName) {
return getComputedStyle(document.documentElement)
.getPropertyValue(varName);
}

This function receives the name of the variables as a parameter and does the following: first, it calls window.getComputedStyle for the document.documentElement (this is typically the <html>), this returns a CSSStyleDeclaration, from where we can call getPropertyValue and get the variable we want.

Here’s a codepen with an example of this technique to play too:

CSS to JS

What about preprocessors?

These techniques both rely in the CSS variables feature, so if you’re using SASS/LESS/Stylus variables, they won’t work.

You could, however, declare CSS variables from the preprocessor variables and then obtain them from JS, like in this next example using SASS:

$red: #ff0000;:root {
--red: $red;
}

Maybe you can even write a cool function/mixin to generate that code in a meta-programming style. Super cool, huh.

I hope you find these techniques useful!

--

--

Front End developer, former game dev. I like making things move on screens.