Ben's notes

Use CSS Variables to style react components on demand

Without any adding any dependencies you can connect react props to raw css at runtime with nothing but css variables (aka “custom properties”). If you add CSS modules on top you don’t have to worry about affecting the global scope so components created in this way can be truly modular and transferrable. I use this with vite.

A quick rehash on how CSS variables are scoped:

/* Scoped globally */
:root {
    --bright-pink: #FF3B9D;
}

/* Scoped to the container */
.containerDiv {
    --pastel-green: #A5FF8A;
}

The idea is that you lift up all the style variables to a main container class for the component. So instead of this:

.someComponent {
    background-color: blue;
}
.someOtherComponent {
    background-color: red;
}

You do this:

.containerDiv {
    --main-color: blue;
    --secondary-color: red;
}

.someComponent {
    background-color: var(--main-color);
}

.someOtherComponent {
    background-color: var(--secondary-color);
}

Then in your component (vite doesn’t require configuring postcss to get css modules):

import css from "./someCss.module.css";

interface SomePromps { 
    mainColor: string;
    secondaryColor: string;
}

export default function SomeComponent({mainColor, secondaryColor}: SomePromps) {
    
    const cssVars = {
        "--mainColor": mainColor,
        "--secondaryColor": secondaryColor,
    } as React.CSSProperties;
	
    return (
        <div className={css.containerDiv} style={cssVars}>
            // This component will automatically update anything
            // in the stylesheet that relies on the variables.
            // Props > re-render > css > display.
            <div className={css.primaryColor}></div>
            <div className={css.secondaryColor}></div>
        </div>
    )
}

Now changing the props will affect the css directly through the variables which will update the element’s style on the page. Adding a dependency do this is unnecesary imo.


Tip 1

To reduce the number of individual color props, and to validate the arguments the end user gives, I use the very small and 0 ext. dep. module: colord to lighten, darken, contrast, and hue rotate a couple of colors to produce more. It can even produce a pallete / collection of harmonious colors from a single argument.

Tip 2

See this post to create a component library using vite: https://dev.to/receter/how-to-create-a-react-component-library-using-vites-library-mode-4lma