Scaling buttons with css custom properties

Custom properties are everywhere now, and for good reason as there are so many useful — and fun! — applications that you can do with them!

A couple of weeks ago, I had an article published on CSS-Tricks where I looked at the benefits of locally scoping custom properties. In that article I quickly mentioned how it could be really useful to create a button scale.

The article ended up being really long, so I cut out the part about creating a button scale with custom properties. I think it’s a really fun application though, as there are two different ways you could approach it.

Scaling buttons

When working with buttons, it’s really common to see something like this:

<button class="btn btn-xs">xs</button>
<button class="btn btn-sm">small</button>
<button class="btn">default</button>
<button class="btn btn-lg">large</button>
<button class="btn btn-xl">xl</button>

By using em for the padding of my button, when I change the font-size, everything will scale all together. So we could do something like this:

.btn-xs { font-size: .75rem; }
.btn-xl { font-size: 1.5rem; }

And it will work. And when someone is asked to add a new .btn-xxl they’ll probably be able to figure it out relatively quickly.

But we can take advantage of CSS custom properties to make something even better here. As I looked at in a previous article, we can use calc() to create a unitless scale custom property. So we can take advantage of that to make create our button scale.

.btn {
  /* using calc to append 'rem' to a unitless custom property */
  font-size: calc(var(--scale) * 1rem);  

  /* rest of the styles */

Now we can do this:

.btn-xs {
  --scale: .75;

.btn-sm {
  --scale: .9;

.btn-lg {
  --scale: 1.3;

.btn-xl {
  --scale: 1.65;

Anyone who wants to create a .btn-xxl won’t even have to think twice here. By using CSS Custom Properties, we’re able to explicitly state the purpose of our numbers and help boost the readability of our code, even if it is a bit more abstract in the initial definition of our .btn.

See the Pen Button scale with CSS Custom Properties by Kevin (@kevinpowell) on CodePen.

Another approach

As I looked at in the CSS-Tricks article, custom properties are really handy for “theming” things within your page.

I think that you could easily do away with the need for a set of buttons like we had above. We only really need one button class, that is set up to be able to scale.

.btn { 
  // 1rem becomes the default
  font-size: calc(var(--btn-scale) * 1rem), 1rem;

Because we have a fallback to 1rem, it will default to that. But, if we want a larger or smaller button, we can easily do that!

.cta {
  --btn-scale: 1.3;
  /* other styles */

.widget {
  --btn-scale: .85;
  /* other styles */

By working like this, we can simplify our markup, eliminate a bunch of CSS, and it’s super easy to understand what’s going on.

See the Pen custom property button scale by Kevin (@kevinpowell) on CodePen.

Don't want to miss an article?

While creating my YouTube videos, I come across a lot of fun snippits of information and little known CSS properties that aren't really worth building full videos about. I share the cool little things I run across (like you read in this post), as well as some design tips and tricks, with a new post every Sunday. Sign up below to never miss a post.

No spam + you can unsub at any time :)