Learn About CSS Custom Properties Through Clever Uses of Them
Tags: codepen, css, customproperties
Published: 2019-01-30 21:29:42

---
title: Learn About CSS Custom Properties Through Clever Uses of Them
published: true
description: CSS custom properties have a ton of use cases. They have all the power of traditional variables, only they follow the cascade like we expect in CSS. Plus you can get clever with their values and combine them with other CSS technology to do very interesting things.
tags: codepen, css, custom properties
---

One of the biggest use-cases for CSS custom properties is theming. Let's consider that for a second. Perhaps you'd set some variables at the highest level you can:

```css
html {
  --column-bg: #ae0001;
  --menu-bg-hover: #680001;
  --active-item: #D3A625;
}

/* Anywhere else in the CSS, you use the variables */
.menu:hover, .menu:focus {
  background: var(--menu-bg-hover);
}
```

Then if you want to change the theme, you have the opportunity to do that _in one isolated place_, which makes things tremendously easier to reason about. Here we'll allow a class change on that root element to change the variables. Anywhere those variables are used will instantly update.

```css
html {
  --column-bg: #ae0001;
  --menu-bg-hover: #680001;
  --active-item: #D3A625;
}
html.alternate-theme {
  --column-bg: #680001;
  --menu-bg-hover: #BE0002;
  --active-item: #00FFBA;
}

/* Anywhere else in the CSS, you use the variables */
.menu:hover, .menu:focus {
  background: var(--menu-bg-hover);
}
```

Here's a wonderful use of theming by Stephanie Liu. It's a recreation of the Slack interface's theming capabilities

{% codepen https://codepen.io/ramenhog/pen/yXYNzz %}

Above, I showed how you might alter the values of CSS custom properties by changing a class, but JavaScript is capable of changing those variable values directly by selecting the element and passing a new value to it, like `el.style.setProperty("--custom-property", "new-value");`, which is how Stephanie is doing it in this demo.

Like any good theming, a user's choice should persist. Stephanie handles this in this demo by plopping the selections into `localStorage`, so check out her JavaScript to see how she's doing that. 


## Adjusting Theme Colors

Another consideration with CSS custom properties being in control of color themes is that sometimes you want a variation of a color, rather than having to pick a whole new second color. Like a button with the chosen color as a border, but a faded version for a background. 

In a post by Ben Szabo, [Theming with CSS variables in RGBA](https://codepen.io/finnhvman/post/theming-with-css-variables-in-rgba), he mentions you could use RGBa or HSLa to make those adjustments with opacity. 

![img](https://thepracticaldev.s3.amazonaws.com/i/3hox8ilmhfreg936owgw.jpg)


If the original color is in RGB or HSL to begin with, the opacity adjustment is easy:

```css
:root {
  --my-color-rgb: 255, 0, 0; 
}

.btn {
  border: 1px solid var(--my-color-rgb);
  background: rgba(var(--my-color-rgb), 0.5);
}
```

I did a demo once where I laid a transparent black gradient over top the color to darken it, so it's not just lightening you can do but darkening as well:

{% codepen https://codepen.io/chriscoyier/pen/ybgNKP/ %}


## Ana Tudor showed us we can make drastic changes to styling with the flip of a CSS custom property toggle.

She called it [DRY switching](https://css-tricks.com/dry-switching-with-css-variables-the-difference-of-one-declaration/). 

The trick is rooted in math and the power of `0` and `1`. With `calc()`, we can multiple values by zero and one and either get nothing or the original value. We can use that base trick for colors, positions, transforms... all kinds of stuff to get hugely different results when that flip is switched.

{% codepen https://codepen.io/thebabydino/pen/JeXMVe/ %}


## Interesting SVG hovers from Marius Niveri

I like this concept in which normal colored SVG has it's color temporarily removed with CSS, moved to a custom property, and then re-applied on hover. Like progressive enhancement coloring!

{% codepen https://codepen.io/m4r1vs/pen/qVReQz/ %}


## Keith Clark combined them with conic gradients to make pie charts

Pass the percentage in right from the markup:

```html
<div class="pie pie--value" style="--percent:65;"></div>
```

Then use that value in a conic-gradient to draw the pie chart.

```css
.pie {
  background-image: conic-gradient(
    rgba(0,0,0,0) calc(3.6deg  var(--percent)),
    rgba(0,0,0,1) calc(3.6deg  var(--percent))
  );
  background-blend-mode: overlay;
  background-position: 50% 50%;
  background-size: 150%; /* oversize bg image to prevent "underdraw" */
  width: 3.75em;
  height: 3.75em;
  border-radius: 50%;
}
```

Keith's demo is fancied up:

{% codepen https://codepen.io/keithclark/pen/aEbEoo/ %}

He's even got a bonus trick in there of using CSS counters to display the percentage value.


## Sérgio Gomes aspect ratio trick with custom properties

What if you could tell an HTML element directly what aspect ratio you wanted it to be? That's documented here. You pass in a ratio directly from the a custom property on the element:

```html
<div style="--aspect-ratio:16/9;">
</div>
```

Then use that value to apply a perfectly sized psuedo element inside that pushes it to that size.

```css
[style="--aspect-ratio"] > :first-child {
  width: 100%;
}
[style="--aspect-ratio"] > img {   height: auto;
} 
@supports (--custom:property) {
  [style="--aspect-ratio"] {
    position: relative;
  }
  [style="--aspect-ratio"]::before {
    content: "";
    display: block;
    padding-bottom: calc(100% / (var(--aspect-ratio)));
  }
  [style*="--aspect-ratio"] > :first-child {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
  }
}
```

Clever stuff.