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>
CSS
@media (min-width: 992px) {
[style*='--space-bottom'] {
margin-bottom: var(--space-bottom);
}
[style*='--space-top'] {
margin-top: var(--space-top);
}
}
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);
}
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>
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);
}
}
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)
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.
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:
Hopefully, though, I'd head them off at point 1 and that'd be the end of it!
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?🙂
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.
Can you show me an example?
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.
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.
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.
„ I was suggesting we talk and ensure the ux and code encapsulates intention the most performant for the now and future…“
I agree 100%!
I'm kinda new to CSS variables and your post helped me understand a little better. Thank you so much!
I'm very happy about that.🙂