When working on frontend projects, sooner or later, we need to create a spacing system. The system should be universal and flexible while ensuring consistency, allowing us to achieve the design requirements effectively.
Over the years, I have developed a useful starting point that I would like to share.
What values should we use? What is a good starting point for the project? It’s time to stop repeating ourselves and prepare a solution using a power of SCSS!
Ready-to-use SCSS margin and padding spacing system with example values
Without further ado, let’s dive right into the SCSS code.
Keep in mind that the estimated spacing values in pixels are calculated based on the assumption that the base font size is 16px, which is the default in most browsers when no font size is specified for the HTML element in CSS.
$spacers: (
0: 0,
1: .25rem, // ~4px
2: .5rem, // ~8px
3: .75rem, // ~12px
4: 1rem, // 16px
5: 1.5rem, // ~24px
6: 2rem, // ~32px
7: 3rem, // ~48px
8: 4rem, // ~64px
9: 6rem, // ~96px
10: 8rem, // ~128px
11: 12rem // ~192px
);
$grid-breakpoints: (
0: 0,
sm: 480px,
md: 768px,
lg: 1200px
);
@mixin media-breakpoint-up($breakpoint) {
@if ($breakpoint != 0) {
@media (min-width: map-get($grid-breakpoints, $breakpoint)) {
@content;
}
} @else {
@content;
}
}
@each $bname, $bvalue in $grid-breakpoints {
@include media-breakpoint-up($bname) {
$bname: if($bname != 0, "-#{$bname}-", "");
@each $key, $value in $spacers {
/* Margin spacers */
.u-m#{$bname}#{$key} {
margin: $value !important;
}
.u-mt#{$bname}#{$key} {
margin-top: $value !important;
}
.u-mr#{$bname}#{$key} {
margin-right: $value !important;
}
.u-mb#{$bname}#{$key} {
margin-bottom: $value !important;
}
.u-ml#{$bname}#{$key} {
margin-left: $value !important;
}
.u-mx#{$bname}#{$key} {
margin-right: $value !important;
margin-left: $value !important;
}
.u-my#{$bname}#{$key} {
margin-top: $value !important;
margin-bottom: $value !important;
}
/* Negative margin spacers */
.u-nm#{$bname}#{$key} {
margin: -$value !important;
}
.u-nmt#{$bname}#{$key} {
margin-top: -$value !important;
}
.u-nmr#{$bname}#{$key} {
margin-right: -$value !important;
}
.u-nmb#{$bname}#{$key} {
margin-bottom: -$value !important;
}
.u-nml#{$bname}#{$key} {
margin-left: -$value !important;
}
.u-nmx#{$bname}#{$key} {
margin-right: -$value !important;
margin-left: -$value !important;
}
.u-nmy#{$bname}#{$key} {
margin-top: -$value !important;
margin-bottom: -$value !important;
}
/* Padding spacers */
.u-p#{$bname}#{$key} {
padding: $value !important;
}
.u-pt#{$bname}#{$key} {
padding-top: $value !important;
}
.u-pr#{$bname}#{$key} {
padding-right: $value !important;
}
.u-pb#{$bname}#{$key} {
padding-bottom: $value !important;
}
.u-pl#{$bname}#{$key} {
padding-left: $value !important;
}
.u-px#{$bname}#{$key} {
padding-right: $value !important;
padding-left: $value !important;
}
.u-py#{$bname}#{$key} {
padding-top: $value !important;
padding-bottom: $value !important;
}
}
}
}
See it on GitHub Gist: spacers.scss.
Understanding how a responsive margin and padding spacing system works
The code pretty much speaks for itself, but let’s walk through it.
- First, we create a SCSS list of
$spacers
with the values present in the project. - We supplement this with breakpoint values in the variable
$grid-breakpoints
(the screen widths where the layout changes its properties). - We create a mixin called
media-breakpoint-up
, which allows us to easily create responsive styles in line with the mobile-first design philosophy. - We conclude with the main part, which involves generating the appropriate code using an SCSS loops.
- As a result, we have ready-to-use helper classes that include margins, paddings, and breakpoints. The utility classes prefixed with
u-
represent a practical application of namespaces found in CSS architectures such as SMACSS, ITCSS, and BEMIT, enabling us to better organize our stylesheets.
Example usage of utility spacing classes and values
You can directly use CSS class names in the class attribute of HTML elements, as shown in the following example:
<div class="u-m4 u-p4 u-md-m6 u-md-p6">
Element
</div>
Alternatively, you can use the map-get
SCSS function to retrieve a specific value from the $spacers
list, as demonstrated in this example:
.element {
margin: map-get($spacers, 4);
padding: map-get($spacers, 4);
@include media-breakpoint-up(md) {
margin: map-get($spacers, 6);
padding: map-get($spacers, 6);
}
}
Further reading
The spacing system described above is inspired by the approach of the Bootstrap CSS framework. If you want to learn more, I encourage you to explore the spacing and breakpoints in Bootstrap 5.
Share
Thanks for reading. If you liked it, consider sharing it with friends via:
Let's be in touch!
Don't miss other useful posts. Level up your skills with UX, web development, and productivity tips via e-mail.
Comments
If you want to comment, write a post on social media and @mention me or write to me directly on the contact page.