Modularise your SASS

This article focuses on the feature of SASS modules

Modularise your SASS

Hello World. Let's continue learning about SASS and modules in SASS.

In the previous article we learned about nesting and variables. Let's have a look at modules and how they can be used to better structure the styling.

Introduction

SASS Modules are similar to libraries which can be of two types, built in and user-defined. These modules can contain things like styling, functions, mixins, and variables to be used in other SASS files. This makes it easier to

  1. reuse SASS code instead of rewriting the same utilities in multiple files.
  2. maintain splitting SASS code into multiple files making it easier to maintain the code. SASS Partials are files that can be used as modules. These partial files begin with an underscore in their name, for example _partial.scss.

Partials

Partials are files that are not meant to be compiled, only imported, which means that the SASS compiler doesn't create a corresponding CSS file for a partial SASS file. When importing a partial we can ignore the underscore in the name.

@import Rule

SASS imports are similar to CSS imports but are resolved during compilation instead of making a new request for the CSS files.

Let's have a look at how to use SASS imports. In the below table we can see two partial files used to style code blocks and lists, these partials can be imported into the style.scss file to be used in the webpage. When compiled down to CSS we can see that the partials aren't compiled but only the style.scss file is compiled down to style.css and includes the styling from both the partials that are imported.

SCSS CSS
// base/_code.scss

code {
  padding: 0.2rem;
  line-height: 0.75;
}
// base/_lists.scss

ul {
  padding: 0;
  margin: 0;
  list-style-type: none;

  li {
    margin: 0.5rem 0;
  }
}
// style.scss
@import "base/code", "base/lists";

code {
  padding: 0.2rem;
  line-height: 0.75;
}

ul {
  padding: 0;
  margin: 0;
  list-style-type: none;
}

ul li {
  margin: 0.5rem 0;
}


These imports work well but there are known drawbacks of this system that lead to the deprecation of this syntax. The reasons for its deprecation are listed as follows:

  1. Everything is globally accessible once imported
  2. Prefixes are required to prevent namespace collisions.

To move away from this syntax, the @use rule has been introduced in SASS. Let's have a look at it in the next section.

@use Rule

Modules with the @use rule can be imported easily using @use <module_name>;

SCSS CSS
// base/_code.scss

code {
  padding: 0.2rem;
  line-height: 0.75;
}
// base/_lists.scss

ul {
  padding: 0;
  margin: 0;
  list-style-type: none;

  li {
    margin: 0.5rem 0;
  }
}
// style.scss
@use "base/code";
@use "base/lists";

code {
  padding: 0.2rem;
  line-height: 0.75;
}

ul {
  padding: 0;
  margin: 0;
  list-style-type: none;
}

ul li {
  margin: 0.5rem 0;
}


The difference is using @use comes into picture when trying to access different members like functions and mixins. @use is namespaced which means that the import name is used to reference the members.

SCSS CSS
// base/_corners.scss

$radius: 12px;

@mixin rounded {
  border-radius: $radius;
}
// base/_colors.scss
$primary: #43bde2;
// style.scss
@use "base/corners";
@use "base/colors";

button {
  @include corners.rounded;
  background-color: colors.$primary;
}

button {
  border-radius: 12px;
  background-color: #43bde2;
}


The namespaces are automatically defined by the file name but these can be aliased as per a user's requirement. The following example describes how to alias the modules.

SCSS CSS
// base/_corners.scss

$radius: 12px;

@mixin rounded {
  border-radius: $radius;
}
// style.scss
@use "base/corners" as c;

button {
  @include c.rounded;
}

button {
  border-radius: 12px;
}


@use can be combined with @forward to make modules easier to use.

Let's have a look at the @forward rule in the next section.

@forward Rule

This rule is used to load stylesheets and make its members available when a sheet is loaded using the @use rule. This allows a user to organize their SCSS across multiple files and load all of it using a single entry point file.

Suppose we have a folder structure as listed below.

scss
├── base
│   ├── _colors.scss
│   ├── _index.scss
│   └── _mixins.scss
└── style.scss

We can use the @forward rule to load all of our SCSS from the abstract folder into our main folder through the single entry point that is the _index.scss The table below illustrates the use of @forward to group all of the SCSS in the base folder and expose it to be used in the style.scss file.

SCSS CSS
// base/_colors.scss

$primary: #5d3fd3;
// base/_mixins.scss
$radius: 12px;

@mixin rounded {
  border-radius: $radius;
}
// base/_index.scss
@forward '../base/colors';
@forward '../base/mixis';
// style.scss
@use './base';

button {
  @include base.rounded;
  color: base.$primary;
}

button {
  border-radius: 12px;
  color: #5d3fd3;
}


The advantage of using @forward is the ability to control the visibility of an SCSS's stylesheet members. The keywords show and hide can be used to accomplish this. show informs SCSS to expose only the members listed after it. hide informs SCSS to hide all the members listed after it and expose the rest.

The same example as the @forward rule is listed below and herein we are asking the rule to hide the variable $radius and expose the mixin rounded while forwarding the members.

SCSS CSS
// base/_colors.scss

$primary: #5d3fd3;
// base/_mixins.scss
$radius: 12px;

@mixin rounded {
  border-radius: $radius;
}
// base/_index.scss
@forward '../base/colors';
@forward '../base/mixis' hide $radius;
// style.scss
@use './base';

button {
  @include base.rounded;
  color: base.$primary;
}

button {
  border-radius: 12px;
  color: #5d3fd3;
}


Conclusion

We've just learned how SCSS modules work and can be used to structure and organize our files to make it easier to hold larger SCSS projects. Modules make it easier to handle a bigger collection of SCSS stylesheets. Let's have a look at some more features that SASS provides in the next post.