How to build your own Utility classes using plain Scss alone
Tags: saas, frontend, css
Published: 2021-05-14 17:50:08

In this article, we will talk and code about using couple of the amazing Sass features to give us some utility classes for spacing, justify and align content and items in the slickest way I was able to think of using a fairly small amount of code 

Now, the question might be why don't I just use TailwindCss or any other framework where I can just use pre-made utility classes, tbh personally I love Tailwind and might have a future article about it, but to answer the question, maybe you land a job and the company like to do everything pure sass no frameworks and believe me they do exist more than you imagine, receive a recruitment task with the same requirement "pure css or sass" or you just feel interested in trying new stuff


we will be using Scss and I will be leaving a link to a GitHub repo of the code at the end of the article


this article assumes you know how to set Scss to work on your project, it has different ways to it with React.js, vue.js or just static HTML so look into this according to your project


So enough talk let's jump into the code part of it

So there's how your folder structure should look like in regular static project:

Root
 --> Index.html
 --> CSS "left empty" 
 --> Scss
  --> styles.scss

the CSS file should be left untouched as browsers don't understand sass, we transform scss to css through packages like node-sass 
personally I installed sass globally and ran this command in the terminal in my project root folder
`sass --watch scss/styles.scss css/styles.css`
so to sum it up; our main work will be with **syles.scss** and index.html


this is how your index.html should look like at the start

```
<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/styles.css"
    <title>Scss Tutorial</title>
  </head>

  <body>
    <div>

    </div>
  </body>

</html>
```
As you can see pretty basic html file, and it's connected to the css file and not scss file and this because as we mentioned earlier browsers don't  understand scss so we need to convert it to plain css

Now what we aim to accomplish is to make spacing utility classes for margin and padding e.g : `<div class="my-3 ml-2 mx-2 my-auto`

### Spacing Utility Classes
now the idea of using scss in not to create each class on its own but rather create all the classes dynamically with one piece of code 

Granted, it won't be a small piece of code but it will much smaller and faster than creating it using plain css

so this is how you will create it

```
$spaceAmounts: (1, 2, 3, 4, 5, 6, 7, 8, auto);

@each $space in $spaceAmounts {
  @if $space==auto {
    .m-#{$space} {
      margin: #{$space};
    }

    .mx-#{$space} {
      margin-left: #{$space};
      margin-right: #{$space};
    }

    .my-#{$space} {
      margin-top: #{$space};
      margin-bottom: #{$space};

    }

    .ml-#{$space} {
      margin-left: #{$space};
    }

    .mr-#{$space} {
      margin-right: #{$space};
    }

    .mb-#{$space} {
      margin-bottom: #{$space};
    }

    .mt-#{$space} {
      margin-top: #{$space};
    }
  }

  @else {
    .m-#{$space} {
      margin: #{$space}rem;
    }

    .mx-#{$space} {
      margin-left: #{$space}rem;
      margin-right: #{$space}rem;
    }

    .my-#{$space} {
      margin-top: #{$space}rem;
      margin-bottom: #{$space}rem;

    }

    .ml-#{$space} {
      margin-left: #{$space}rem;
    }

    .mr-#{$space} {
      margin-right: #{$space}rem;
    }

    .mb-#{$space} {
      margin-bottom: #{$space}rem;
    }

    .mt-#{$space} {
      margin-top: #{$space}rem;
    }

    .p-#{$space} {
      padding: #{$space}rem;
    }

    .px-#{$space} {
      padding-left: #{$space}rem;
      padding-right: #{$space}rem;
    }

    .py-#{$space} {
      padding-top: #{$space}rem;
      padding-bottom: #{$space}rem;

    }

    .pl-#{$space} {
      padding-left: #{$space}rem;
    }

    .pr-#{$space} {
      padding-right: #{$space}rem;
    }

    .pb-#{$space} {
      padding-bottom: #{$space}rem;
    }

    .pt-#{$space} {
      padding-top: #{$space}rem;
    }
  }
}

```
The idea is simple, you are going to make a variable list of the amounts of space you want to make classes of, then  loop through these amounts and create your own classes, the tricky part is with `margin-auto` utility classes and for that we shall use the if statement of scss ... pretty slick I know

### Align & Justify Utility Classes
now one more trick using the same concept

while working with css3 flex box and grid system, we use css properties like;
`justify-content, align-items, justify-items` a lot and using the same trick we are going to create our own utility classes for them using yet another piece of code
 

```
$alignments: ("center", "space-between", "space-around", "space-evenly", "flex-start", "flex-end");

@each $align in $alignments {
  .justify-#{$align} {
    justify-content: #{$align};
  }

  .items-#{$align} {
    align-items: #{$align};
  }

  .justify-items-#{$align} {
    justify-items: #{$align};
  }

  .content-#{$align} {
    align-content: #{$align};
  }
}
```
now the idea is the same as for spacing but the class names are going to be a bit different, e.g `items-center` class is equal to `align-items: center` css property


### Display and Text-Align Utility Classes
similarly enough we are going to make our display and text-align utility classes 

here's our code for them

#### Display classes
```
$displayProps: ("block", "inline-block", "inline", "flex", "grid", "inline-flex", "inline-grid", "table", "inline-table", "list-item", "none", "contents");

@each $disp in $displayProps {
  .d-#{$disp} {
    display: #{$disp};
  }
}
```
#### Text Align classes
```
$textAlignments: ("left", "right", "center", "revert");

@each $textAlign in $textAlignments {
  .text-#{$textAlign} {
    text-align: #{$textAlign};
  }
}
```
now hit save, make sure new classes are added in your css/styles.css and take a look at all the new utility classes we just created in few minutes using that few lines of code

No it is time to try our classes in the Html file
here's how the body of the html file should look like
```
 <body>
    <div class="d-flex justify-center items-center my-3 mx-auto">
      <div class="pt-2 pb-4 px-3">
        <h3 class="text-center">This plain Scss</h3>
      </div>
      <div class="pt-2 pb-4 px-3">
        <h3 class="text-right">It's amazing</h3>
      </div>
    </div>
    <div class="d-grid scss-grid">
      <div class="px-3 py-2">
        <ul>
          <li>List item</li>
          <li>another list item</li>
          <li>one more of those</li>
        </ul>
      </div>
      <div class="pt-2 pb-3 px-2">
        <h3 class="text-center">Pretty Dope stuff</h3>
        <p class="text-left">Lorem ipsum dolor sit amet consectetur adipisicing elit. Nisi libero maxime adipisci quos,
          asperiores omnis?
        </p>
      </div>
    </div>
  </body>
```
as you can see I have used all the classes we have created to create the following image 
![Final Shape](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/masas9esa0o6bhaij1n2.png)
pretty basic I'm very aware, but I'm sure you too are aware of the possibilities of all you can build with this
you can also realize I have a custom class called **scss-grid** in my second main div, this is a class I applied to this one css property in my main scss file
```
.scss-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
```
I will also encourage you to try on your own to solve the scss-grid issue with the same way we did with all those utility classes, maybe create some classes for box-shadow, font-size, font-weight, text and background colors and many more and share with me your thoughts

Thank you for joining me today 

you can also reach me on twitter  @SuperSarhan15

you can check the code from here: [GitHubRepo](https://github.com/AhmedSarhan/scss-utilites-)
I also included the plain css files so you can read through them