Partials & @use
One giant stylesheet becomes painful fast. Real projects split styles into many small files: one for colours and sizes, one for buttons, one for the header. Sass joins them into one CSS file when it compiles, so you get tidy source code and a single download for the browser.
In this lesson you will create partials, load them with the @use rule, reach their variables, mixins and functions through a namespace, keep helpers private, and configure a module's settings with with. This is the module system, the modern way to organise Sass.
Partials
A partial is a Sass file whose name starts with an underscore, such as _tokens.scss. The underscore tells the compiler "do not turn this file into its own CSS file; it is only meant to be loaded by others". A typical small project:
scss/
_tokens.scss colours, sizes, mixins, functions
_reset.scss a few base rules
main.scss the entry file: loads the othersWhen you load a partial you leave out both the underscore and the extension: @use "tokens" finds _tokens.scss. Paths are relative to the file that contains the @use, so a file in components/ loads the tokens with @use "../tokens".
Loading a module with @use
Each file you load with @use is a module. Its CSS is added to the output, and its variables, mixins and functions become available through a namespace, which by default is the last part of the file name.
Here is the partial with the shared settings:
// scss/_tokens.scss
$brand: #cc6699 !default;
$radius: 6px !default;
$-gap: 3px; // private: starts with - or _
@mixin card-shadow {
box-shadow: 0 2px 8px rgb(0 0 0 / 0.12);
}
@function space($n) {
@return $n * 0.25rem;
}The reset partial holds plain rules:
// scss/_reset.scss
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; }And the entry file loads both and uses the tokens through the tokens. namespace:
// scss/main.scss
@use "reset";
@use "tokens";
.card {
border: 2px solid tokens.$brand;
border-radius: tokens.$radius;
padding: tokens.space(4);
@include tokens.card-shadow;
}Compiling main.scss gives one CSS file. The reset rules come first, because reset was loaded first:
*, *::before, *::after {
box-sizing: border-box;
}
body {
margin: 0;
}
.card {
border: 2px solid #cc6699;
border-radius: 6px;
padding: 1rem;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}Notice the namespace syntax: tokens.$brand for a variable (the $ comes after the dot), tokens.space(4) for a function and @include tokens.card-shadow for a mixin. Every name tells the reader exactly which file it comes from.
Two rules of @use:
@userules must come before any other rules in the file (only@forwardand variable declarations may come earlier).- A module is loaded once, however many files
@useit. If_buttons.scssand_forms.scssboth usereset, its CSS still appears only once in the output.
Built-in modules work the same way
Sass ships with built-in modules such as sass:math, sass:color and sass:string. You load them with the same rule, and this is the one kind of @use the editor on this site can run, because it does not need other files:
@use "sass:math";
@use "sass:color";
$brand: #cc6699;
.badge {
padding: math.div(12px, 2) 12px;
background: color.scale($brand, $lightness: 80%);
border: 1px solid $brand;
}.badge {
padding: 6px 12px;
background: rgb(96%, 88%, 92%);
border: 1px solid #cc6699;
}You will explore every built-in module in Built-in Modules and Colour Functions.
Changing the namespace
You can pick a shorter namespace with as, or remove it with as *:
@use "tokens" as t; // t.$brand, t.space(2)
@use "sass:math" as m; // m.div(10px, 2)
@use "tokens" as *; // $brand, space(2), @include card-shadowas * makes the module's members global in this file, as if they were written here. It is convenient for one well-known settings file, but if two modules have a member with the same name, Sass reports an error, and readers can no longer see where a name comes from. Use it sparingly.
Private members
A member whose name starts with - or _, such as $-gap above, is private: it can be used inside its own file but not from outside. If line 2 of main.scss tries .x { width: tokens.$-gap; }, compiling fails:
Private members can't be accessed from outside their modules.
╷
2 │ .x { width: tokens.$-gap; }
│ ^^^^^^^^^^^^
╵
main.scss 2:13 root stylesheetLibrary authors use this to hide helpers that might change, so users depend only on the public names.
Configuring a module with with()
Variables marked !default can be set from outside when you load the module, using with:
// scss/main.scss
@use "tokens" with ($brand: #0e7490, $radius: 12px);
.btn {
background: tokens.$brand;
border-radius: tokens.$radius;
}.btn {
background: #0e7490;
border-radius: 12px;
}Configuration happens the first time a module is loaded, so put the configured @use in your entry file before anything else loads that module. Only !default variables can be configured; trying to configure any other variable is an error. This is how frameworks let you set the brand colour without editing their files.
Here is what the compiled CSS looks like on a page, with the configured teal brand:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Configured module</title>
<style>
body { font-family: system-ui, sans-serif; padding: 1.5rem; }
/* compiled from main.scss with $brand: #0e7490 and $radius: 12px */
.btn {
background: #0e7490;
border-radius: 12px;
color: white;
border: 0;
padding: 0.75rem 1.25rem;
font: inherit;
}
</style>
</head>
<body>
<p>Kochi ferry tickets: ₹20 per trip.</p>
<button class="btn" type="button">Book a seat</button>
</body>
</html>Common mistakes
tokens.brandor$tokens.brand. The$goes after the namespace:tokens.$brand.@useafter a rule. Move all@uselines to the top of the file.- Loading the same module twice in one file. Sass reports "There's already a module with namespace". Use one
@useper module. - Configuring a module after it was already loaded elsewhere. Put the
@use ... with (...)first in the entry file. - Compiling partials directly. Partials are loaded by the entry file; compile
main.scss, not_tokens.scss.
Key points
- Partials are files that start with
_; they are loaded by other files, not compiled on their own. @use "file"loads a module once, adds its CSS, and gives access to its members through a namespace:file.$var,file.fn(),@include file.mixin.as namechanges the namespace andas *removes it; useas *sparingly.- Members starting with
-or_are private to their module. @use "file" with ($var: value)configures!defaultvariables the first time the module is loaded.
Exercise
Plan a small project for a Pune cycle-rental shop. Write _settings.scss with $accent: #ea580c !default and $radius: 4px !default, plus a pill($bg) mixin that sets background, white color and border-radius: 999px. In main.scss, load it with the namespace s, configure $accent to #16a34a, and write a .rent-btn rule that includes the mixin with the accent colour and uses the radius for outline-offset.
Show solution
// _settings.scss
$accent: #ea580c !default;
$radius: 4px !default;
@mixin pill($bg) {
background: $bg;
color: white;
border-radius: 999px;
}
// main.scss
@use "settings" as s with ($accent: #16a34a);
.rent-btn {
@include s.pill(s.$accent);
outline-offset: s.$radius;
}The compiled .rent-btn gets background: #16a34a, because the configured value replaces the !default one. as s and with can be used together on one @use.
Quick Quiz
1. Which line loads _buttons.scss from the same folder?
Leave out the underscore and extension; Sass finds the partial.
2. After @use "tokens";, how do you read its $brand variable?
The namespace comes first, then the member with its $.
3. Two partials both @use "reset". How many times does the reset CSS appear in the output?
A module is loaded only once, no matter how many files use it.
4. Which variable can be set with @use "tokens" with ($radius: 8px)?
Configuration works on public !default variables.
Learn Sass with a mentor
Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
