Sass @import extends CSS’s @import to load Sass/CSS files at compile time. It is deprecated—this tutorial explains how it worked, why it causes problems, how it differs from @use, and how to migrate, with five compiled examples.
01
Status
Deprecated
02
Behavior
Global members
03
Nesting
Scoped CSS
04
Plain CSS
Passthrough
05
Migrate
@use / @forward
06
Practice
5 examples
Concept
What Is Sass @import?
Official docs: Sass extends CSS’s @import with the ability to import Sass and CSS stylesheets, providing access to mixins, functions, and variables and combining multiple stylesheets’ CSS together. Unlike plain CSS imports (extra HTTP requests while rendering), Sass imports are handled entirely during compilation.
Same basic syntax as CSS @import, plus comma-separated lists of files.
Imported content is evaluated as if it appeared at the @import location.
Members become globally available after the import.
Importing the same file again evaluates it again (CSS can duplicate).
💡
Beginner tip
Read legacy @import so you can follow older tutorials—then rewrite new work with @use so every name has a clear namespace.
Why
⚠️ What’s Wrong With @import?
Official docs list serious issues:
All variables, mixins, and functions become globally accessible—hard to find definitions.
Libraries must prefix every member to avoid collisions.
@extend is also global and hard to predict.
Each import re-executes the file and can bloat CSS output.
No private members or private placeholder selectors for downstream files.
The module system (@use / @forward) addresses all of these problems.
Foundation
📝 Syntax
styles.scss
// Single file (extension optional)
@import "foundation/code";
// Multiple files in one rule
@import "foundation/code", "foundation/lists";
// Nested (scopes CSS)
.theme-sample {
@import "theme";
}
Behavior
⚙️ How Import Evaluation Works
Official docs: when Sass imports a file, that file is evaluated as though its contents appeared directly in place of the @import. Mixins, functions, and variables become available, and CSS is inserted at that point. Members defined before the import are also visible inside the imported file.
⚠️
Duplicate imports
If the same stylesheet is imported more than once, it is evaluated again each time. Style rules can appear multiple times in the CSS output.
Paths
🔍 Finding the File
Extensions are optional: @import "variables" loads .scss, .sass, or .css.
Use forward slashes (even on Windows).
Relative paths resolve first; load paths are a fallback.
Partials start with _; omit the underscore when importing.
A folder’s _index.scss loads when you import the folder.
Scope
🎯 Nested Imports
Official docs: imports can nest inside style rules or plain CSS at-rules. Imported CSS is nested in that context. Top-level mixins/functions/variables from the nested import are only available in that nested context.
For authors of the imported file, prefer a mixin (or meta.load-css() in modern code) instead of relying on nested imports.
CSS
📄 Plain CSS @imports
Sass leaves some imports as real CSS @imports in the output when:
Official docs: prefer @use. Sass provides a migration tool that converts most @import-based code automatically.
Old
Modern
@import "tokens";
@use "tokens"; then tokens.$gap
Library barrel file
@forward partials from one entry
Nested @import
Mixin include or meta.load-css()
Compare
🔁 Differences From @use
@import (legacy)
@use (modern)
Member scope
Global
Current file only (namespaced)
Load once?
No—re-evaluates each time
Yes—once per module
Nesting
Allowed
Must be at file top
URLs per rule
Comma lists OK
One URL per rule
Status
Deprecated
Recommended
Cheat Sheet
⚡ Quick Reference
Goal
Legacy
Prefer instead
Load members + CSS
@import "x";
@use "x";
Library entrypoint
Import many files
@forward + one @use
Scope third-party CSS
Nested @import
meta.load-css() / mixin
Real CSS import
@import "x.css";
Same (passthrough) or link in HTML
Hands-On
Examples Gallery
These examples show how legacy @import behaves so you can recognize and migrate it. Prefer @use in new projects. Open View Compiled CSS for verified output.
📚 Legacy Patterns
How @import combined files and shared members.
Example 1 — Basic Multi-File Import
Comma-separated imports pull CSS from multiple partials.
Same CSS result as Example 2, but names are namespaced and the module loads once. This is the pattern to use going forward.
Applications
🚀 When You Still See @import
Legacy codebases — older tutorials and packages still use it.
LibSass projects — no @use; stuck on imports until you switch compilers.
Plain CSS imports — fonts/CDN/media-query imports that must stay in CSS.
Migration in progress — mixed @import + @use during a transition.
🧠 How Compilation Works
1
Write @import
Point at a partial, folder, or plain CSS URL.
Source
2
Resolve or passthrough
Sass file? Inline it. Plain CSS import pattern? Leave for the browser.
Compile
3
Share globals
Members become global (legacy behavior) and CSS is emitted.
Emit
4
✓
Plan the migration
Replace with @use / @forward before Dart Sass 3.0.
Watch Out
⚠️ Common Pitfalls
Using it in new code — deprecated; will be removed in Dart Sass 3.0.
Duplicate CSS — importing the same file twice re-emits its rules.
Name collisions — everything is global after import.
Assuming browser behavior — Sass imports are compile-time unless they match plain-CSS rules.
Writing @import "file.css" for Sass loading — the .css suffix forces a plain CSS import.
Pro Tips
💡 Best Practices
✅ Do
Prefer @use and @forward for all new work
Run the Sass migrator on legacy entrypoints
Keep genuine CSS imports (fonts/CDN) as plain CSS when needed
Document any temporary @import left during migration
Upgrade to Dart Sass so you can leave LibSass behind
❌ Don’t
Start new projects on @import
Import the same stylesheet repeatedly for “safety”
Rely on global members without namespaces
Nest imports when a mixin would be clearer
Ignore deprecation warnings from Dart Sass 1.80+
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about Sass @import
Legacy compile-time imports—deprecated in favor of @use.
5
Core concepts
⚠️01
Status
deprecated
1.80+
📦02
Scope
global members
Legacy
🔁03
Replace
@use / @forward
Modern
📄04
CSS import
passthrough rules
Browser
✓05
Next
migrate early
Plan
❓ Frequently Asked Questions
Yes. As of Dart Sass 1.80.0, @import is deprecated and will be removed in Dart Sass 3.0.0. Prefer @use (and @forward for library entrypoints).
It loads another Sass or CSS stylesheet at compile time, combining CSS and making mixins, functions, and variables available. Unlike browser CSS @import, it does not add extra HTTP requests at render time.
It makes members global, encourages long prefixes, makes @extend unpredictable, can duplicate CSS when a file is imported multiple times, and has no private members.
Prefer rewriting imports as @use / @forward. Sass provides an official migration tool that converts most @import-based code automatically.
When the URL ends with .css, starts with http(s)://, is written as url(), or includes media queries—Sass leaves those as CSS @import in the output.
Yes. Nested imports scope the imported CSS under a selector or at-rule. For new code, prefer a mixin or meta.load-css() instead.
Did you know?
Official Sass docs ship a migrator that can convert most @import-based projects to @use automatically—point it at your entrypoints and review the diff.
Sass @import was the old way to combine stylesheets and share members. It is deprecated as of Dart Sass 1.80 and scheduled for removal in 3.0. Learn it to maintain legacy code—then migrate to @use and @forward.