React Component Variants Using CSS Variables

Three different ways of using CSS variables in your stylesheets and their use in React components.

Lucas Andión
Trabe
4 min readMay 13, 2021

--

Photo by Kira auf der Heide on Unsplash

In a previous story, we discussed component theming using CSS variables.

The method we are going to discuss in this story uses the same concepts in a different way. It can also be combined with theming to create CSS variants for your library components.

Using CSS variables

CSS variables are widely supported in all modern browsers. They are also referred to as custom properties because they are, in fact, properties once you define them

Support of CSS variables. Updated version here

A basic example of using CSS variables in your page would be defining them on the root and using them on subsequent elements, like this.

Here we define --main-color , --white-color and --black-color and use them to set colors in paragraphs and items with the class title.

The result of using the previous classes on a h1 with .title class and a paragraph.

Attaching the variables to the HTML element will make them available to all the rules. Alternatively, you could use the :root pseudo-class.

We will try to demonstrate three alternative methods of using variables to get two button variants.

Using common variables in specific classes

Not much to see here, we just define color variables on a CSS rule that makes them available and use them on our red and green classes. We’ll call this “classic” mode for short.

Using theme bounded variables

This is the technique we described in our previous story. We define our CSS variables on a custom theme that encloses the rest of the components we want to style.

This is more suitable to theme a bunch of components defining CSS variables on a common ancestor and then wrapping your components. These components use the variables declared on the theme that wraps them.

Using scoped CSS properties

This last method is the one we want to introduce in this post.

In this one, we define a style in a more generic class using a CSS variable. Then in specialized subclasses, we fill the variable with the value we want.

If you want a “default” background color you can pass to the var function a second argument. This will be the fallback to use when the property has not been set.

The result of all three experiments can be seen in this image. The resulting buttons look the same, but the techniques are way different.

Creating our React component

We will use a combination of these three techniques to create a Button component with two styles (primary and secondary) and two sizes that can also be themeable.

A rather boring component, but the button.module.css is where we use variables to create our Button variants.

As you can see the root class uses font, color, background and padding variables.

In this case, we fill those variables in the specific classes using more variables. So, we are using the third technique introduced, but the values of those variables are still missing.

This is where we use theming. The root_{s,m,primary,secondary} classes fill padding, color, and font values, but those come from a Theme component.

This Theme imports some base classes (where we’ll set the common variables) and a couple of custom theme classes with theme-specific vars: jediTheme and sithTheme. We can select the current theme using the name prop.

  • Our base theme sets the spacing and font variables used on our Button.
  • Our two custom themes fill the themable variables.

Using our Component

To finish our example, let’s test our different button components creating some regular and small buttons using the two different themes.

This will look like this.

As you can see, we simplified the example to the bare minimum. Using combinations of the three techniques described you could create highly customizable components that reuse most of the javascript & CSS.

--

--

Lucas Andión
Trabe

Galician. Software developer @trabe. Bike lover, beer enthusiast, mad traveler, beagle friend, surfer wannabe — https://andion.github.io