@use and @import rules in SCSS

Written by Minna Ylitalo on 14th October 2020

(Last updated 5th July 2023)

Intro - what is SCSS?

SCSS is a CSS preprocessor used to keep your CSS more organised and concise. It provides tools like mixins, variables and functions (in SCSS these are called members) as well as allows you to nest your styles. Browsers can't read SCSS so your code needs to go through a packaging process before it's sent off to the browser as plain CSS.

The styles of larger projects are usually divided into partials to make it easier to find the code you need to target. Having a clear file structure keeps your project easier to manage and make changes in, and breaking your styles into smaller sections helps you to keep track.

Partials can be loaded inside other stylesheets to create global styles for components and sections on your site, which in turn helps to keep your code DRY and readable. This is where we're going to be looking at the @use rule and how it differs from its predecessor @import.

Visit the official Sass guide to find out more about SCSS.

@import vs. @use

Fundamentally both rules do the same thing - load members inside another module. The main differences is how they handle members. @import makes everything globally accessible in the target file. This enables an endless chain of imported files where it's difficult to trace where your variables and mixins are coming from. It also allows for overlap and makes it difficult to trace back why your perfect css breaks. This is a problem especially with complex file structures and projects with multiple contributors and global libraries, which is why @import is no longer recommended by Sass.

How @use rule works

Same as @import, @use rule enables us to break our stylesheet into more practical, smaller sections and load them inside other stylesheets. The key difference is how you access the original files' members. To do this you will need to refer to the namespace of the original file. Here's an example of simple SCSS partials.

_Define basic button variables and mixins in the button.scss partial:

// _button.scss

$radius: 0.5rem;

@mixin buttonSmall {
    border-radius: $radius;
    padding: 1rem;
}

To use your _button.scss members in another element add your @use rule to the top of your file. You will need to refer to the original file when using its members. You do this by adding its namespace in front of the member. By default the namespace is the name of the original file.

// _box.scss

@use 'button';

.boxButton {
    @include button.buttonSmall;
    margin: 1rem + button.$radius;
}

_In plain CSS box.scss looks like this:

//_box.scss

.boxButton {
	border-radius: 0.5rem;
	padding: 1rem;
	margin: 1.5rem;
}

In this example we can quickly see where the members used in the _box.scss file were defined. If we had used the @import instead of @use we would have no direct way of knowing the origin and value of our members. This also allows the use of very simple names like radius and border, which helps to keep your code tidy.

With @import giving your members such simple names would override any previously set $radius variable and button mixin. This would mean being more careful as to what you are overriding. It comes in handy when using a global library - you can use “generic” names for things without fear of overwriting things on specific projects.

@forward

There's more you can do with loading your stylesheets in SCSS but one of the most useful ones in relation to @use is the @forward rule. It allows you to gain access to members through another file. Here's a quick example.

// _button.scss

$padding: 1rem;
//_box.scss

@use 'button';

.boxButton {
	padding: button.$padding; // 1rem;
}
//_newBox.scss

@use 'box';

.newBoxButton {
	padding: button.$padding; // ???
}

The _newBox.scss can't access the variable from _button.scss. We will need to pass the styles explicitly forward. The @forward rule loads the styles as if they were defined inside the target file.

//_box.scss

@use 'button';
@forward 'button'; // recreates the variable from _button.scss inside the current file

.boxButton {
	padding: button.$padding; // 1rem;
}
//_newBox.scss

@use 'box';

.newBoxButton {
	padding: box.$padding // 1rem;
}

Get familiar with the @use rule to keep your projects organised and tidy and to avoid CSS conflicts and bugs. Use @forward to control which files can access which members. For more tips and tricks check out the Sass documentation and to bring your projects up to date have a look at the migration tool.

This article was posted in Development by Minna Ylitalo