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>
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;
}
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 setmargin -
p- for classes that setpadding
Where sides is one of:
-
t- for classes that setmargin-toporpadding-top -
b- for classes that setmargin-bottomorpadding-bottom -
l- for classes that setmargin-leftorpadding-left -
r- for classes that setmargin-rightorpadding-right -
x- for classes that set both*-leftand*-right -
y- for classes that set both*-topand*-bottom - blank - for classes that set a
marginorpaddingon all 4 sides of the element
Where size is one of:
-
0- for classes that eliminate themarginorpaddingby setting it to0 -
1- (by default) for classes that set themarginorpaddingto$spacer * .25 -
2- (by default) for classes that set themarginorpaddingto$spacer * .5 -
3- (by default) for classes that set themarginorpaddingto$spacer -
4- (by default) for classes that set themarginorpaddingto$spacer * 1.5 -
5- (by default) for classes that set themarginorpaddingto$spacer * 3 -
auto- for classes that set themarginto auto
Define Our Requirements
Our focus is to generate all the css classes of the format {property}{sides}-{size}.
For example:
-
m-0tom-5andm-auto -
p-0top-5 -
mt-0,mb-0,ml-0,mr-0tomt-5,mb-5,ml-5,mr-5andmt-auto,mb-auto,ml-auto,mr-auto -
pt-0,pb-0,pl-0,pr-0topt-5,pb-5,pl-5,pr-5 -
mx-0tomx-5andmy-0tomy-5andmx-auto,my-auto -
px-0topx-5andpy-0tomy-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;
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;
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;
}
}
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;
}
}
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;
}
}
}
Till now, we have covered the following cases:
-
m-0tom-5andm-auto -
p-0top-5
Let's focus on next two cases:
-
mt-0,mb-0,ml-0,mr-0tomt-5,mb-5,ml-5,mr-5andmt-auto,mb-auto,ml-auto,mr-auto -
pt-0,pb-0,pl-0,pr-0topt-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);
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;
}
}
}
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;
}
}
}
}
Now we only left with following two cases to generate:
-
mx-0tomx-5andmy-0tomy-5andmx-auto,my-auto -
px-0topx-5andpy-0tomy-5
To generate classes for x and y axises let's create a new sass:list.
$axises: (x, y);
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}.";
}
}
}
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";
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
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>
Complete source code is available here.
Thank you for reading. Your appreciation is my motivation!
Follow me on social media:
- Linkedin: mazeduldev
- Twitter: @mazeduldev
- Github: mazeduldev
- Website: mazedul.dev
Top comments (3)
Alhamdulillah, i have complete this article , this is amazing. Thank you Mazedul Islam vai.
Great content! Very straight forward and easy to follow. Thanks for sharing.
Good to know that you liked it 🙌