DEV Community

Cover image for Generate bootstrap like spacing classes using SASS
Mazedul Islam
Mazedul Islam

Posted on • Edited on

Generate bootstrap like spacing classes using SASS

Last month we have initialized a new project with Angular and Angular Material. As time goes, I have noticed that some of my colleagues are often writing inline styles for margin and padding.

<div style="margin-top: 5px; margin-bottom: 5px">
  With inline style
</div>
Enter fullscreen mode Exit fullscreen mode

Some of them (including me) are creating similar css classes for almost every components wherever needed.

.set-padding {
  padding: 10px 0;
}
.left-spacer {
  margin-left: 10px;
}
Enter fullscreen mode Exit fullscreen mode

Then I realized that we are actually missing bootstrap like margin and padding classes. One of my colleague suggested to use Tailwind CSS. However, as we are already using Angular Material for our component library, installing a css framework only for some spacing classes will be an overkill for sure. So, I decided to write these classes on my own.

Bootstrap Classes: A Closer Look

According to the documentation of Bootstrap 4 its spacing classes have the following format:

The classes are named using the format {property}{sides}-{size} for xs and {property}{sides}-{breakpoint}-{size} for sm, md, lg, and xl.

Where property is one of:

  • m - for classes that set margin
  • p - for classes that set padding

Where sides is one of:

  • t - for classes that set margin-top or padding-top
  • b - for classes that set margin-bottom or padding-bottom
  • l - for classes that set margin-left or padding-left
  • r - for classes that set margin-right or padding-right
  • x - for classes that set both *-left and *-right
  • y - for classes that set both *-top and *-bottom
  • blank - for classes that set a margin or padding on all 4 sides of the element

Where size is one of:

  • 0 - for classes that eliminate the margin or padding by setting it to 0
  • 1 - (by default) for classes that set the margin or padding to $spacer * .25
  • 2 - (by default) for classes that set the margin or padding to $spacer * .5
  • 3 - (by default) for classes that set the margin or padding to $spacer
  • 4 - (by default) for classes that set the margin or padding to $spacer * 1.5
  • 5 - (by default) for classes that set the margin or padding to $spacer * 3
  • auto - for classes that set the margin to auto

Define Our Requirements

Our focus is to generate all the css classes of the format {property}{sides}-{size}.

For example:

  1. m-0 to m-5 and m-auto
  2. p-0 to p-5
  3. mt-0, mb-0, ml-0, mr-0 to mt-5, mb-5, ml-5, mr-5 and mt-auto, mb-auto, ml-auto, mr-auto
  4. pt-0, pb-0, pl-0, pr-0 to pt-5, pb-5, pl-5, pr-5
  5. mx-0 to mx-5 and my-0 to my-5 and mx-auto, my-auto
  6. px-0 to px-5 and py-0 to my-5

Notice, we are omitting {property}{sides}-{breakpoint}-{size} pattern, which is not in the scope of this article.

SASS Implementation

I am going to use SCSS syntax, you can also use the original SASS if you find that easier to use.

Let's create a new file _spaces.scss. Filename starts with _ because I want to make it a partial sass file. You can check the sass guide if you do not know what partial sass file means.

Create a variable $spacer with the default value for space.

// _spaces.scss
$spacer: 1rem !default;
Enter fullscreen mode Exit fullscreen mode

Then create a sass:map with keys from 0 to 5 and auto and set the calculated value for each keys.

$spacers: (
  0: 0,
  1: $spacer * 0.25,
  2: $spacer * 0.5,
  3: $spacer,
  4: $spacer * 1.5,
  5: $spacer * 3,
  auto: auto,
) !default;
Enter fullscreen mode Exit fullscreen mode

Now, let's loop through the map and generate classes from m-0 to m-5 and m-auto.

@each $key, $value in $spacers {
  // generate m-* classes
  .m-#{$key} {
    margin: #{$value} !important;
  }
}
Enter fullscreen mode Exit fullscreen mode

We can also generate padding classes inside this loop. Let's generate classes from p-0 to p-5.

@each $key, $value in $spacers {
  // generate m-* classes
  .m-#{$key} {
    margin: #{$value} !important;
  }

  // generate p-* classes
  .p-#{$key} {
    padding: #{$value} !important;
  }
}
Enter fullscreen mode Exit fullscreen mode

However, this code will also generate .p-auto { padding: auto !important; } which is incorrect. So, we need to exclude auto key when generating .p-* classes.

@each $key, $value in $spacers {
  // generate m-* classes
  .m-#{$key} {
    margin: #{$value} !important;
  }

  // generate p-* classes excluding key = auto
  @if $key != auto {
    .p-#{$key} {
      padding: #{$value} !important;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Till now, we have covered the following cases:

  1. m-0 to m-5 and m-auto
  2. p-0 to p-5

Let's focus on next two cases:

  1. mt-0, mb-0, ml-0, mr-0 to mt-5, mb-5, ml-5, mr-5 and mt-auto, mb-auto, ml-auto, mr-auto
  2. pt-0, pb-0, pl-0, pr-0 to pt-5, pb-5, pl-5, pr-5

Now we need to generate classes which can target specific side. Therefore create a sass:list containing all the sides.

$sides: (top, bottom, left, right);
Enter fullscreen mode Exit fullscreen mode

For each key presents in the $spacers map we need to generate classes combining each direction/side. Therefore, we need nested loop like this.

@each $key, $value in $spacers {
  @each $side in $sides {
    // generate m* classes
    .m#{str-slice($side, 0, 1)}-#{$key} {
      margin-#{$side}: #{$value} !important;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Same as before, we can generate padding classes (excluding auto key) inside this loop.

@each $key, $value in $spacers {
  @each $side in $sides {
    // generate m* classes
    .m#{str-slice($side, 0, 1)}-#{$key} {
      margin-#{$side}: #{$value} !important;
    }

    // generate p* classes excluding key = auto
    @if $key != auto {
      .p#{str-slice($side, 0, 1)}-#{$key} {
        padding-#{$side}: #{$value} !important;
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Now we only left with following two cases to generate:

  1. mx-0 to mx-5 and my-0 to my-5 and mx-auto, my-auto
  2. px-0 to px-5 and py-0 to my-5

To generate classes for x and y axises let's create a new sass:list.

$axises: (x, y);
Enter fullscreen mode Exit fullscreen mode

Same as before, for each key value presents in $spacers combining each axis presents in $axis list we need to generate classes. So, we need to use nested loops again.

@each $key, $value in $spacers {
  @each $axis in $axises {
    @if $axis == x {
      // generate classes for x axis

      // generate mx-* classes
      .m#{$axis}-#{$key} {
        margin-left: #{$value} !important;
        margin-right: #{$value} !important;
      }

      // generate px-* classes excluding key = auto
      @if $key != auto {
        .p#{$axis}-#{$key} {
          padding-left: #{$value} !important;
          padding-right: #{$value} !important;
        }
      }
    } @else if $axis == y {
      // generate classes for y axis

      // generate my-* classes
      .m#{$axis}-#{$key} {
        margin-top: #{$value} !important;
        margin-bottom: #{$value} !important;
      }

      // generate py-* classes excluding key = auto
      @if $key != auto {
        .p#{$axis}-#{$key} {
          padding-top: #{$value} !important;
          padding-bottom: #{$value} !important;
        }
      }
    } @else {
      @error "Unknown axis #{$axis}.";
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Usage

If your project setup supports scss file, then you can import this file into your root style file using @use rule.

// styles.scss file, in the same directory of _spaces.scss
@use "./spaces";
Enter fullscreen mode Exit fullscreen mode

If you need compiled css, then you can install SASS on your machine and use the following command to generate spaces.css file.

sass _spaces.scss spaces.css
Enter fullscreen mode Exit fullscreen mode

After adding this, now we can use bootstrap like css classes in our html code.

<div class="my-2 px-2">
  Styled with bootstrap like classes!
</div>
Enter fullscreen mode Exit fullscreen mode

Complete source code is available here.


Thank you for reading. Your appreciation is my motivation!

Follow me on social media:

Top comments (3)

Collapse
 
mannydiera profile image
Manny Diera

Great content! Very straight forward and easy to follow. Thanks for sharing.

Collapse
 
mazid1 profile image
Mazedul Islam

Good to know that you liked it 🙌

Collapse
 
rhrabin profile image
RH Rabin

Alhamdulillah, i have complete this article , this is amazing. Thank you Mazedul Islam vai.