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-top
orpadding-top
-
b
- for classes that setmargin-bottom
orpadding-bottom
-
l
- for classes that setmargin-left
orpadding-left
-
r
- for classes that setmargin-right
orpadding-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
orpadding
on all 4 sides of the element
Where size
is one of:
-
0
- for classes that eliminate themargin
orpadding
by setting it to0
-
1
- (by default) for classes that set themargin
orpadding
to$spacer * .25
-
2
- (by default) for classes that set themargin
orpadding
to$spacer * .5
-
3
- (by default) for classes that set themargin
orpadding
to$spacer
-
4
- (by default) for classes that set themargin
orpadding
to$spacer * 1.5
-
5
- (by default) for classes that set themargin
orpadding
to$spacer * 3
-
auto
- for classes that set themargin
to auto
Define Our Requirements
Our focus is to generate all the css classes of the format {property}{sides}-{size}
.
For example:
-
m-0
tom-5
andm-auto
-
p-0
top-5
-
mt-0
,mb-0
,ml-0
,mr-0
tomt-5
,mb-5
,ml-5
,mr-5
andmt-auto
,mb-auto
,ml-auto
,mr-auto
-
pt-0
,pb-0
,pl-0
,pr-0
topt-5
,pb-5
,pl-5
,pr-5
-
mx-0
tomx-5
andmy-0
tomy-5
andmx-auto
,my-auto
-
px-0
topx-5
andpy-0
tomy-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-0
tom-5
andm-auto
-
p-0
top-5
Let's focus on next two cases:
-
mt-0
,mb-0
,ml-0
,mr-0
tomt-5
,mb-5
,ml-5
,mr-5
andmt-auto
,mb-auto
,ml-auto
,mr-auto
-
pt-0
,pb-0
,pl-0
,pr-0
topt-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-0
tomx-5
andmy-0
tomy-5
andmx-auto
,my-auto
-
px-0
topx-5
andpy-0
tomy-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: mazedul-islam
- Twitter: @mazedul__islam
- Github: mazid1
- Website: mazedulislam.com
Top comments (3)
Great content! Very straight forward and easy to follow. Thanks for sharing.
Good to know that you liked it 🙌
Alhamdulillah, i have complete this article , this is amazing. Thank you Mazedul Islam vai.