Let’s break down import
, use
, and forward
in SCSS. While import
is an older feature, use
and forward
are part of the newer module system, which is the recommended way to manage SCSS files.
1. @import
(Older, Legacy)
The @import
rule allows you to include content from other SCSS or CSS files directly into your current file. When Sass compiles, it takes the content of the imported file and places it where @import
was declared.
Key Characteristics:
- Global Scope: Variables, mixins, and functions defined in an imported file become globally available in the importing file. This can lead to name collisions if not managed carefully.
- Compilation: Sass resolves
@import
statements at compile time, effectively merging the files. - Deprecation: While still supported for backward compatibility, Sass officially discourages the use of
@import
in favor of the module system (@use
and@forward
).
Example:
Let’s say you have _variables.scss
:
// _variables.scss
$primary-color: #007bff;
$font-stack: Helvetica, sans-serif;
And main.scss
:
// main.scss
@import 'variables'; // No .scss extension needed
body {
font-family: $font-stack;
color: $primary-color;
}
.button {
background-color: $primary-color;
padding: 10px 20px;
}
Output CSS:
body {
font-family: Helvetica, sans-serif;
color: #007bff;
}
.button {
background-color: #007bff;
padding: 10px 20px;
}
Why it’s less preferred now: With @import
, everything from _variables.scss
pollutes the global scope of main.scss
. If you have many partials, it becomes harder to track where a variable or mixin was defined, and name conflicts are more likely.
2. @use
(Newer, Module System)
The @use
rule loads mixins, functions, and variables from other Sass stylesheets and makes them available locally with a namespace. This is the primary way to consume Sass modules.
Key Characteristics:
- Namespacing: By default, everything loaded with
@use
is namespaced based on the filename. This prevents name collisions. - Private Members: Variables, mixins, and functions that start with
_
(underscore) or-
(hyphen) are considered private and won’t be exposed by@use
. - Single Import: A module is only executed once, even if used multiple times. This helps with performance and prevents duplicate CSS.
- Configuration: You can configure variables in the used module at the time of
@use
.
Example:
Let’s redefine _variables.scss
:
// _variables.scss
$primary-color: #007bff;
$_private-color: #ccc; // This is private and won't be available
And _mixins.scss
:
// _mixins.scss
@mixin flex-center {
display: flex;
justify-content: center;
align-items: center;
}
Now in main.scss
:
// main.scss
@use 'variables'; // This creates a 'variables' namespace
@use 'mixins'; // This creates a 'mixins' namespace
body {
font-family: variables.$font-stack; // Accessing a variable using its namespace
color: variables.$primary-color;
@include mixins.flex-center; // Using a mixin with its namespace
}
.button {
background-color: variables.$primary-color;
}
Output CSS:
body {
font-family: Helvetica, sans-serif;
color: #007bff;
display: flex;
justify-content: center;
align-items: center;
}
.button {
background-color: #007bff;
}
Benefits of @use
:
- Clarity: It’s immediately clear where a variable or mixin comes from due to the namespace.
- Collision Prevention: Namespaces virtually eliminate name conflicts.
- Encapsulation: Private members keep module internals tidy.
Aliasing: You can also provide a custom namespace:
// main.scss
@use 'variables' as var; // Custom namespace 'var'
body {
color: var.$primary-color;
}
3. @forward
(Newer, Module System)
The @forward
rule allows you to “re-export” members (mixins, functions, and variables) from another Sass stylesheet, making them available through your stylesheet. This is useful for building libraries or creating a single entry point for a collection of Sass partials.
Key Characteristics:
- Re-exporting: It doesn’t load the members into the current file’s scope; it just makes them available to other files that
@use
your file. - No Namespace for Forwarded Members: When you
@use
a file that@forward
s another, the forwarded members appear directly under the namespace of the file you@use
d, not nested further. - Hiding/Showing: You can explicitly choose which members to forward or hide.
Example:
Imagine you’re building a design system.
_colors.scss
:
// _colors.scss
$brand-blue: #007bff;
$text-dark: #333;
_typography.scss
:
// _typography.scss
$font-family-base: Arial, sans-serif;
@mixin heading-style {
font-weight: bold;
line-height: 1.2;
}
Now, you want to create a single _design-system.scss
file that acts as an entry point for your design system, forwarding all relevant pieces.
_design-system.scss
:
// _design-system.scss
@forward 'colors';
@forward 'typography';
Finally, in your main.scss
:
// main.scss
@use 'design-system'; // Use the main design-system module
body {
font-family: design-system.$font-family-base; // Accessing forwarded variable
color: design-system.$text-dark; // Accessing forwarded variable
}
h1 {
@include design-system.heading-style; // Using forwarded mixin
color: design-system.$brand-blue;
}
Output CSS:
body {
font-family: Arial, sans-serif;
color: #333;
}
h1 {
font-weight: bold;
line-height: 1.2;
color: #007bff;
}
Key Difference with @use
for the Consumer:
Notice how design-system.$font-family-base
is used. Even though $font-family-base
originally came from _typography.scss
(which _design-system.scss
forwarded), it’s directly accessible under the design-system
namespace. If you had directly @use 'typography';
in main.scss
, you’d use typography.$font-family-base
.
Benefits of @forward
:
- Organized Libraries: Helps create well-structured Sass libraries by presenting a clean API.
- Single Entry Point: Consumers only need to
@use
one file to get access to many related modules. - Abstraction: The consumer doesn’t need to know the internal structure of your library, just the API exposed by the forwarded members.
Summary Table:
Feature | Purpose | Scope of Members | Namespacing (Default) | Use Case | Status |
---|---|---|---|---|---|
@import | Include content directly | Global | No | Legacy, simple file inclusion | Discouraged |
@use | Load members for local use | Local to the importing file | Yes (filename-based) | Consuming modules, avoiding collisions | Recommended |
@forward | Re-export members to other stylesheets | Not directly in current file | No (for forwarded) | Building libraries, creating entry points | Recommended |
In modern Sass development, you should primarily focus on using @use
and @forward
for better organization, maintainability, and collision prevention. Reserve @import
only for existing legacy projects or when importing plain CSS files that Sass doesn’t process.
Leave a Reply