Responsive margin and padding spacing system with SCSS

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.

  1. First, we create a SCSS list of $spacers with the values present in the project.
  2. We supplement this with breakpoint values in the variable $grid-breakpoints (the screen widths where the layout changes its properties).
  3. We create a mixin called media-breakpoint-up, which allows us to easily create responsive styles in line with the mobile-first design philosophy.
  4. We conclude with the main part, which involves generating the appropriate code using an SCSS loops.
  5. 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.