Get a CSS Custom Property value with JavaScript

Categories


CSS Custom Properties are handy for making highly configurable CSS components and themes, but that’s not their only handy use. Sometimes you might want to do something like send some information to some JavaScript.

In the past, I’ve done something like this to get the current breakpoint without querying the window width:

Code language
CSS
body::before {
  content: 'mobile';
  display: none;
}

@media screen and (min-width: 30rem) {
  body::before {
    content: 'large-mobile';
  }
}

@media screen and (min-width: 70rem) {
  body::before {
    content: 'desktop';
  }
}
Code language
JavaScript
function getBreakpoint() {
  return getComputedStyle(document.querySelector('body'), ':before').getPropertyValue('content').replace(/\'|"/g, '');
}

This approach very much does the job, but with CSS Custom Properties, we can have a little more flexibility and using properties to send values feels more...um...right.

The getCSSCustomProp function permalink

I needed to see if CSS scroll snapping was supported in my JavaScript component and messed around for too long looking for a JavaScript solution. It dawned on me that CSS could cut the mustard for me and communicate the status back up to my JavaScript with a little bit of magic.

I set a default value on the component like this:

Code language
CSS
.my-component {
  --supports-scroll-snap: 0;
}

Then, using @supports, I can do this:

Code language
CSS
@supports (scroll-snap-type: x mandatory) {
  .my-component {
    --supports-scroll-snap: 1;
  }
}

Then, finally, the JavaScript runs this:

Code language
JavaScript
const myComponent = document.querySelector('.my-component');
const isSnapSupported = getCSSCustomProp('--supports-scroll-snap', myComponent, 'boolean');

That all runs off this function:

Code language
JavaScript
/**
 * Pass in an element and its CSS Custom Property that you want the value of.
 * Optionally, you can determine what datatype you get back.
 *
 * @param {String} propKey
 * @param {HTMLELement} element=document.documentElement
 * @param {String} castAs='string'
 * @returns {*}
 */
const getCSSCustomProp = (propKey, element = document.documentElement, castAs = 'string') => {
  let response = getComputedStyle(element).getPropertyValue(propKey);

  // Tidy up the string if there's something to work with
  if (response.length) {
    response = response.replace(/\'|"/g, '').trim();
  }

  // Convert the response into a whatever type we wanted
  switch (castAs) {
    case 'number':
    case 'int':
      return parseInt(response, 10);
    case 'float':
      return parseFloat(response, 10);
    case 'boolean':
    case 'bool':
      return response === 'true' || response === '1';
  }

  // Return the string response by default
  return response;
};

Wrapping up permalink

This trick isn’t dissimilar to the original hack that I did with breakpoints on the body. The main difference now is that we’re passing actual properties, rather than hiding values in content. It feels a hell of a lot cleaner.

You can grab this function from this Gist and hopefully, it’ll help you out.


Comments

If you liked this post, you might like these ones, too

  1. What are design tokens?

    Design tokens are just spicy variables, right? Wrong! They are an extremely versatile way of sharing design properties and in this tutorial, you’ll learn how they work.

    Continue
  2. Getting started with CSS Custom Properties

    Custom properties in CSS are exceptionally useful, not just for tokenising your CSS, but also for abstracting complexity and interactivity into smaller, easier to manage pieces. This short guide will get you up to speed with how they work and how to use them.

    Continue
  3. Easy horizontal and vertical centering in CSS

    🔥 A handy quick tip.

    Continue

Become a supporter by joining the Piccalilli Membership

For $5 per month, you get access to a private, friendly Discord community, a regular newsletter, huge discounts on courses and free access to all premium tutorials.

Most importantly, by becoming a supporter, you help make as much content, free-to-everyone as possible on this site, which benefits everyone. As a member, you also get an ad-free experience around the site.

Support Piccalilli by becoming a member

Sign up for updates

Stay up to date with updates from Piccalilli. You’ll get alerted as soon as any new content gets published. You’ll also get updates on upcoming courses and membership features! You can unsubscribe at any time, too.