DEV Community

Cover image for The power of CSS Variables 💪: A flexible solution for spacing utilities
Karsten Biedermann
Karsten Biedermann

Posted on

The power of CSS Variables 💪: A flexible solution for spacing utilities

In modern web development, flexibility and adaptability are key aspects that determine the effectiveness and aesthetics of a webpage. CSS variables offer just this flexibility, allowing developers to define values centrally and then reuse and adjust them across the project as needed. A particularly practical application for CSS variables is the control of spacing. This article highlights how CSS variables provide a higher degree of flexibility compared to traditional methods such as modified classes.

For my Themex project, I've employed spacing utilities in the form of CSS variables. If you want to learn more about the Themex project, please visit here: https://app.themexproject.com

Spacing with CSS Variables

Using spacing variables in web projects allows for flexible adjustment of spacings at different places on a webpage, such as the top or bottom margin of an element. This can significantly speed up and simplify development, as changes to spacing sizes can be easily made globally.

A key advantage: Fewer CSS classes

A significant advantage of using CSS variables for spacing is the reduction in the need to write numerous specific CSS classes. Traditionally, developers had to create separate classes for different spacings, leading to a bloated stylesheet and increased complexity. With CSS variables, you can instead define uniform variables for spacings and apply them, simplifying the codebase and easing maintenance.

Adding vertical spacing

To add spacing variables to an element, use the element's style attribute and define the desired variables as follows:

HTML

<div style="--space-top: 30px; --space-bottom: 100px;"></div>
Enter fullscreen mode Exit fullscreen mode

CSS

@media (min-width: 992px) {
  [style*='--space-bottom'] {
    margin-bottom: var(--space-bottom);
  }
  [style*='--space-top'] {
    margin-top: var(--space-top);
  }
}
Enter fullscreen mode Exit fullscreen mode

In this example, the element is given a top spacing (space-top) of 30px and a bottom spacing (space-bottom) of 100px.

Default behavior for mobile devices

By default, the spacing variables are configured so that the defined spacings are automatically halved for screen widths below 992px. This ensures optimized display on mobile devices without the need for additional adjustments.

[style*='--space-top'] {
  margin-top: calc(var(--space-top) / 2);
}

[style*='--space-bottom'] {
  margin-bottom: calc(var(--space-bottom) / 2);
}
Enter fullscreen mode Exit fullscreen mode

Overriding values for mobile devices

If specific spacings for mobile devices are desired that do not follow the automatic halving, they can be explicitly overridden. This is done by using variables with the suffix -[device]:

HTML

<div style="--space-top-sm: 80px; --space-bottom-sm: 80px;"></div>
Enter fullscreen mode Exit fullscreen mode

CSS

/* small devices */
[style*='--space-top-sm'] {
  margin-top: var(--space-top-sm);
}

[style*='--space-bottom-sm'] {
  margin-bottom: var(--space-bottom-sm);
}

/* medium devices */
@media (min-width: 768px) {
  [style*='--space-top-md'] {
    margin-top: var(--space-top-md);
  }

  [style*='--space-bottom-md'] {
    margin-bottom: var(--space-bottom-md);
  }
}
Enter fullscreen mode Exit fullscreen mode

Why inside a style element and not directly in CSS?

For example, to allow components to be reusable, it is important not to hard-code spacing specifications within the component itself. Of course, it's possible to define default behaviours, but experience shows that this doesn't add value. In 80% of cases, spacing properties are overridden.

Here is an example of how it can work in practice (build with Themex): https://example.themexproject.com/

Top comments (11)

Collapse
 
fpaghar profile image
Fatemeh Paghar

One more thing to think about is how using CSS variables for spacing can make websites better for people with disabilities. If developers use the same spacing for everything, it helps people using screen readers or keyboards to navigate more easily. When spacing is clear and consistent, it makes the website easier to read and use for everyone. This focus on accessibility matches with what modern web development believes in, making sure that websites can be used by everyone, no matter their abilities or what device they use.

Collapse
 
moopet profile image
Ben Sinclair

A significant advantage of using CSS variables for spacing is the reduction in the need to write numerous specific CSS classes

You only really need to write so many classes if you're using utility classes, which is effectively the same as inlining your styles.

The example you give, where you use style="--space-top: 30px;[...]" in your HTML is going to be really confusing to future maintainers, since it explicitly says how the element should be spaced, but then that number is overridden by a media query in a separate file.

Instead of doing any of this, I'd have a consistent set of base styles, and if I need to deviate from them at any point I'd go through two stages:

  1. ask the designer why there needed to be a special case
  2. add a variant class and deal with it if necessary.

Hopefully, though, I'd head them off at point 1 and that'd be the end of it!

Collapse
 
karsten_biedermann profile image
Karsten Biedermann

What if you want to define a margin for different breakpoints? What if a margin fits for desktop but then no longer works for mobile? That's not really scalable. In the end, you write countless classes. Then it becomes unclear. Documentation is then also an issue in itself, which is always neglected. And why should I question the competence of a designer?🙂

Collapse
 
moopet profile image
Ben Sinclair

You don't need to write loads of classes to handle different breakpoints, though. The minimum you need is to style each semantic element proportionately. Next ehancement would be to style them with different nesting, then at different breakpoints, and last would be to style them with semantic classes for any edge cases. If the minimal case, you do your design in a consistent manner and you don't need classes at all.

Thread Thread
 
karsten_biedermann profile image
Karsten Biedermann

Can you show me an example?

Collapse
 
cjcheshire profile image
Chris Cheshire

It’s not uncommon for a little friction between Engineering and design. There’s a healthy amount to ensure good ux as well as good code.

We all make mistakes and sometimes the design can be a few pixels out. It’s good practice to discuss this with them. It could be a mistake or intentional. If intentional this can spark a good conversation about the system and if this should then be a rule to use moving forward. That would also mean you wouldn’t need to have lots of rogue calculations but a variable for these situations.

Thread Thread
 
karsten_biedermann profile image
Karsten Biedermann • Edited

I get the point. But as a frontend developer you can have expertise in design, but most people don't have this expertise. Initially, it's not about the pixels but about the aesthetics. Why should I put myself above a graphic designer and presume to know better? In 15 years, I've met very few graphic designers who didn't understand their job properly.

Thread Thread
 
cjcheshire profile image
Chris Cheshire

I think you’ve missed my point. You’ve written some good concepts here to identify system values that can be used for spacing amongst other things.

You can have 15 years experience and still make a mistake. A good front end engineer would ask, is this value intentional or should I use the usual value we have in our system as variable x.

If they’ve made a mistake, you use the usual. If it’s intentional, now you can either capture that in your system as a variable to reuse elsewhere in your codebase or if just a one off do something adhoc.

I was not implying we go around knowing someone’s job better, I was suggesting we talk and ensure the ux and code encapsulates intention the most performant for the now and future.

Thread Thread
 
karsten_biedermann profile image
Karsten Biedermann

„ I was suggesting we talk and ensure the ux and code encapsulates intention the most performant for the now and future…“
I agree 100%!

Collapse
 
michellesanseverino profile image
Michelle Sanseverino • Edited

I'm kinda new to CSS variables and your post helped me understand a little better. Thank you so much!

Collapse
 
karsten_biedermann profile image
Karsten Biedermann

I'm very happy about that.🙂