Using CSS custom properties to reduce the size of your CSS
Tags: css, tutorial, beginners, webdev
Published: 2019-11-26 13:08:52

Unlike SASS variables, CSS Custom Properties can be modified in class selectors, allowing you to create abstractions and reduce the size of your CSS.

Let me show you an example!

Here's a quick video tutorial. Jump this section if you prefer to read the article.

{% youtube fQ7ILuIw1z0 %}

In the [CodyHouse Framework](https://codyhouse.co/ds/components), we use the `.grid-gap-{size}` utility classes to set the spacing among grid items:

```scss
.grid {
  display: flex;
  flex-wrap: wrap;

  > * {
    flex-basis: 100%;
  }
}

.grid-gap-xxxs {
  margin-bottom: calc(-1 * var(--space-xxxs));
  margin-left: calc(-1 * var(--space-xxxs));

  > * {
    margin-bottom: var(--space-xxxs);
    margin-left: calc(var(--space-xxxs));
  }
}

.grid-gap-xxs {
  margin-bottom: calc(-1 * var(--space-xxs));
  margin-left: calc(-1 * var(--space-xxs));

  > * {
    margin-bottom: var(--space-xxs);
    margin-left: calc(var(--space-xxs));
  }
}

.grid-gap-xs {
  margin-bottom: calc(-1 * var(--space-xs));
  margin-left: calc(-1 * var(--space-xs));

  > * {
    margin-bottom: var(--space-xs);
    margin-left: calc(var(--space-xs));
  }
}

.grid-gap-sm {
  margin-bottom: calc(-1 * var(--space-sm));
  margin-left: calc(-1 * var(--space-sm));

  > * {
    margin-bottom: var(--space-sm);
    margin-left: calc(var(--space-sm));
  }
}

.grid-gap-md {
  margin-bottom: calc(-1 * var(--space-md));
  margin-left: calc(-1 * var(--space-md));

  > * {
    margin-bottom: var(--space-md);
    margin-left: calc(var(--space-md));
  }
}

.grid-gap-lg {
  margin-bottom: calc(-1 * var(--space-lg));
  margin-left: calc(-1 * var(--space-lg));

  > * {
    margin-bottom: var(--space-lg);
    margin-left: calc(var(--space-lg));
  }
}

.grid-gap-xl {
  margin-bottom: calc(-1 * var(--space-xl));
  margin-left: calc(-1 * var(--space-xl));

  > * {
    margin-bottom: var(--space-xl);
    margin-left: calc(var(--space-xl));
  }
}

.grid-gap-xxl {
  margin-bottom: calc(-1 * var(--space-xxl));
  margin-left: calc(-1 * var(--space-xxl));

  > * {
    margin-bottom: var(--space-xxl);
    margin-left: calc(var(--space-xxl));
  }
}

.grid-gap-xxxl {
  margin-bottom: calc(-1 * var(--space-xxxl));
  margin-left: calc(-1 * var(--space-xxxl));

  > * {
    margin-bottom: var(--space-xxxl);
    margin-left: calc(var(--space-xxxl));
  }
}
```

Because there's a lot of repetition, a few weeks ago, we've decided to use CSS custom properties to simplify these classes.

The first step was creating an abstraction that contains the code we repeat for each utility class:

```scss
[class*="grid-gap"] {
  margin-bottom: calc(-1 * var(--grid-gap, 1em));
  margin-left: calc(-1 * var(--grid-gap, 1em));

  > * { 
    margin-bottom: var(--grid-gap, 1em); 
    margin-left: var(--grid-gap, 1em);
  }
}
```

This attribute selector looks for classes that contain the "grid-gap" string (all the grid-gap utility classes). Note that we've replaced the `--space-unit` variables with a new `--grid-gap` variable.

In our `.grid` class, we set the `--grid-gap` variable equal to 0 (default value).

```scss
.grid {
  --grid-gap: 0px;
  display: flex;
  flex-wrap: wrap;

  > * {
    flex-basis: 100%;
  }
}
```

Now we can modify, for example, the `.grid-gap-xxxxs` class as the following:

```scss
.grid-gap-xxxxs { --grid-gap: var(--space-xxxxs); }
```

We no longer need all the chunk of code about margins; we can just modify the value of the `--grid-gap` variable.

If we do the same for all the utility classes, we end up with the following:

```scss
.grid {
  --grid-gap: 0px;
  display: flex;
  flex-wrap: wrap;

  > * {
    flex-basis: 100%;
  }
}

[class*="grid-gap"] {
  margin-bottom: calc(-1 * var(--grid-gap, 1em));
  margin-left: calc(-1 * var(--grid-gap, 1em));

  > * { 
    margin-bottom: var(--grid-gap, 1em); 
    margin-left: var(--grid-gap, 1em);
  }
}

.grid-gap-xxxxs { --grid-gap: var(--space-xxxxs); }
.grid-gap-xxxs  { --grid-gap: var(--space-xxxs); }
.grid-gap-xxs   { --grid-gap: var(--space-xxs); }
.grid-gap-xs    { --grid-gap: var(--space-xs); }
.grid-gap-sm    { --grid-gap: var(--space-sm); }
.grid-gap-md    { --grid-gap: var(--space-md); }
.grid-gap-lg    { --grid-gap: var(--space-lg); }
.grid-gap-xl    { --grid-gap: var(--space-xl); }
.grid-gap-xxl   { --grid-gap: var(--space-xxl); }
.grid-gap-xxxl  { --grid-gap: var(--space-xxxl); }
.grid-gap-xxxxl { --grid-gap: var(--space-xxxxl); }
```

This optimization reduces the CSS size of this example by more than half! Obviously, you can apply this technique only when it's possible to abstract some rules (I'm not suggesting that CSS custom properties will reduce by half the size of your CSS). But still, this tutorial is just an example of code optimization made possible by using CSS variables.

ps: CSS Variables are supported in [all modern browsers](https://caniuse.com/#feat=css-variables).

Originally published at [CodyHouse.co](https://codyhouse.co/blog/post/using-css-custom-properties-to-reduce-the-size-of-your-css)