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:

SCSS
// _variables.scss
$primary-color: #007bff;
$font-stack: Helvetica, sans-serif;

And main.scss:

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:

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:

SCSS
// _variables.scss
$primary-color: #007bff;
$_private-color: #ccc; // This is private and won't be available

And _mixins.scss:

SCSS
// _mixins.scss
@mixin flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

Now in main.scss:

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:

SCSS
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:

SCSS
// 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 @forwards another, the forwarded members appear directly under the namespace of the file you @used, 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:

SCSS
// _colors.scss
$brand-blue: #007bff;
$text-dark: #333;

_typography.scss:

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:

SCSS
// _design-system.scss
@forward 'colors';
@forward 'typography';

Finally, in your main.scss:

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:

SCSS
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:

FeaturePurposeScope of MembersNamespacing (Default)Use CaseStatus
@importInclude content directlyGlobalNoLegacy, simple file inclusionDiscouraged
@useLoad members for local useLocal to the importing fileYes (filename-based)Consuming modules, avoiding collisionsRecommended
@forwardRe-export members to other stylesheetsNot directly in current fileNo (for forwarded)Building libraries, creating entry pointsRecommended

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.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *