Them­ing with CSS Cus­tom Properties

Publisher: TJ Fogarty

Modified: 2018-03-13

I remem­ber scoff­ing at the thoughts of vari­ables in CSS. Haha. Oh inter­net, we have Sass!” Alas, I was a fool. Now it’s get­ting to the stage where I might say Haha. Oh inter­net, we have CSS!” when faced with the option of using a pre-proces­sor. There’s still a few things I use pre-proces­sors or post-proces­sors for such as nest­ing and split­ting files, but beyond that I’d be just as hap­py using vanil­la CSS.

I’m going to be show­ing the code used on this site at the moment, one dif­fer­ence being the name of some of the cus­tom prop­er­ties, but beyond that it’s the same. As I’m using Craft, I’ll be explain­ing this with the Twig tem­plat­ing lan­guage. If you use Word­Press you can do this with PHP or Twig (which I wrote an arti­cle about if you’re inter­est­ed), but the idea can be applied any­where from serv­er-side ren­der­ing to JavaScript in the client.

The CSS #

To cre­ate a cus­tom prop­er­ty, we can use the :root selec­tor and pass it prop­er­ties that begin with --. This tells the brows­er that they’re cus­tom prop­er­ties and the val­ues can be what­ev­er we want. In this case we’re using colours.

We’re going to del­care two colours; pri­ma­ry and sec­ondary. The c pre­fix here is more of a visu­al cue to let us know these are colours should we need reminding:

:root {
  --c-primary: #7B296E;
  --c-secondary: #AFA73A;
}

I like to keep these at the top of a file where I make base styles such as on the body tag, but I might end up mov­ing them to their own file in the future if it gets a bit unwield­ly. In any case they’re set now and we can use them by call­ing the var() func­tion and pass­ing one of these prop­er­ty names:

a {
  color: var(--c-primary);
}

a:hover {
  color: var(--c-secondary);
}

By using these, the project becomes instant­ly the­me­able. I’m sure more con­sid­er­a­tion needs to be tak­en with big­ger projects; maybe you don’t want all of them to change, or have more con­trol over what gets updat­ed. In this case you can cre­ate new cus­tom prop­er­ties based on exist­ing ones:

:root {
  --c-primary: #7B296E;
  --c-secondary: #AFA73A;
  --c-hero-title: var(--c-primary);
}

This way we can re-use exist­ing val­ues with­out dupli­ca­tion, but also tar­get spe­cif­ic ones in cer­tain cas­es if we need to.

The Tem­plates #

In my case, I’m select­ing a ran­dom theme on every page load, so it makes more sense for me to have every­thing relat­ed to the them­ing in Twig files. Oth­er­wise if I scoped my themes in CSS to a class I’d have to update the Twig file and the CSS when a new one gets added or removed. If you’re mak­ing a theme selec­tor then it can be nec­ces­sary if they change based on a class get­ting added to an ele­ment in the DOM. To each their own real­ly, we just want to build cool stuff.

In our default Twig lay­out file, I’ve updat­ed the open­ing html tag to this:

<html lang="en" {% include 'components/_style-switcher' %}>

This will inline some CSS to over­ride the orig­i­nal vari­ables. So what’s in _style-switcher.twig?

{% set themes = [
  {
    'primary': '#ff3b3f',
    'secondary': '#fcd200'
  },
  {
    'primary': '#7B296E',
    'secondary': '#AFA73A'
  },
  {
    'primary': '#02847F',
    'secondary': '#D99104'
  },
  {
    'primary': '#75003E',
    'secondary': '#8B8F00'
  },
  {
    'primary': '#8F0000',
    'secondary': '#005656'
  }
] %}

{% set theme = random(themes) %}
style="--c-primary: {{ theme['primary'] }}; --c-secondary: {{ theme['secondary'] }};"

It’s an array of objects, each one con­tain­ing a pri­ma­ry and sec­ondary key. {% set theme = random(themes) %} will select a ran­dom item from the array which we can then use to set the val­ue of the vari­able. In this approach it won’t set a unique one every sin­gle time, such is the nature of ran­dom I guess. So you could refresh the page a few times before a new one is chosen.

One approach to avoid this might be to set a cook­ie with the name of the cho­sen theme. On the next page load you could check if the new ran­dom­ly cho­sen one is the same as the one in the cook­ie. If so, try again, and repeat until you have a new one, and set that in the cookie.

If you’re using JavaScript, you can use the fol­low­ing to update cus­tom properties:

document.querySelector('html').style.setProperty('--c-primary', 'purple');

Here’s what my site end­ed up look­ing like:

Con­clu­sion #

There’s a range of ways you can approach this, and the eas­i­est in some cas­es might be to do this with JavaScript if you don’t have access to the serv­er code side of things. Cus­tom Prop­er­ties absolute­ly opens up a world of dynam­i­cism on the web, and you can do a whole lot more than theme with them. I usu­al­ly pick a new fea­ture such as this and try apply it to my own work, be it exist­ing or new, to have a play with it. And what’s code if it’s not play­ful at times?