DEV Community

loading...
Cover image for How to build your own Utility classes using plain Scss alone

How to build your own Utility classes using plain Scss alone

Ahmed Sarhan
I'm a Software Engineer interested in React.js, Vue.js, GraphQl, AWS and The cloud
・5 min read

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>
Enter fullscreen mode Exit fullscreen mode

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;
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

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};
  }
}
Enter fullscreen mode Exit fullscreen mode

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};
  }
}
Enter fullscreen mode Exit fullscreen mode

Text Align classes

$textAlignments: ("left", "right", "center", "revert");

@each $textAlign in $textAlignments {
  .text-#{$textAlign} {
    text-align: #{$textAlign};
  }
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

as you can see I have used all the classes we have created to create the following image
Final Shape
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));
}
Enter fullscreen mode Exit fullscreen mode

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
I also included the plain css files so you can read through them

Discussion (0)