Partials & @import
Partials & @import in SASS
As your stylesheets grow larger, organizing your code becomes crucial. SASS provides a powerful system for breaking your styles into smaller, manageable files called partials. Understanding partials and the @import directive is essential for maintaining clean, organized codebases.
What are Partials?
A partial is a SASS file that contains snippets of CSS code that you want to include in other SASS files. Partials are named with a leading underscore (_), which tells SASS not to compile them into standalone CSS files. Instead, they are meant to be imported into other SASS files.
Example Partial: _variables.scss
// _variables.scss
$primary-color: #3498db;
$secondary-color: #2ecc71;
$font-family: "Helvetica Neue", Arial, sans-serif;
$base-font-size: 16px;
$line-height: 1.6;
// Spacing
$spacing-unit: 8px;
$spacing-small: $spacing-unit;
$spacing-medium: $spacing-unit * 2;
$spacing-large: $spacing-unit * 3;
// Breakpoints
$breakpoint-mobile: 480px;
$breakpoint-tablet: 768px;
$breakpoint-desktop: 1024px;
The @import Directive
The @import directive allows you to include the content of one SASS file in another. When you import a partial, SASS includes the content of that file where the @import statement appears. This lets you modularize your styles and keep related code together.
Basic @import Syntax
// main.scss
@import "variables";
@import "mixins";
@import "base";
@import "layout";
@import "components/buttons";
@import "components/cards";
body {
font-family: $font-family;
color: $text-color;
}
How @import Works
When SASS encounters an @import directive, it looks for the file in the same directory (or specified path), reads its contents, and includes them at that exact location in the compiling process. This happens before any CSS is generated.
Import Process Example
// _colors.scss
$primary: blue;
$secondary: green;
// _typography.scss
$font-main: Arial, sans-serif;
$font-size: 16px;
// main.scss
@import "colors";
@import "typography";
body {
font-family: $font-main;
font-size: $font-size;
color: $primary;
}
// Compiled to:
body {
font-family: Arial, sans-serif;
font-size: 16px;
color: blue;
}
Import Order Matters
The order in which you import files is critical because CSS follows the cascade principle. Later rules override earlier rules if they have the same specificity. Additionally, you must import variables before you use them.
Correct Import Order
// main.scss
// 1. Configuration (variables, functions)
@import "config/variables";
@import "config/functions";
// 2. Tools (mixins, placeholders)
@import "tools/mixins";
@import "tools/placeholders";
// 3. Base styles (resets, typography)
@import "base/reset";
@import "base/typography";
// 4. Layout
@import "layout/grid";
@import "layout/header";
@import "layout/footer";
// 5. Components
@import "components/buttons";
@import "components/forms";
@import "components/cards";
// 6. Pages
@import "pages/home";
@import "pages/about";
// 7. Themes
@import "themes/dark";
// 8. Utilities (should be last to override)
@import "utilities/helpers";
@import "utilities/spacing";
File Organization Strategies
A well-organized SASS project typically uses a structured folder system with multiple partials. Here's a common architecture pattern called the 7-1 pattern (7 folders, 1 main file).
7-1 Architecture Pattern
sass/
│
├── abstracts/
│ ├── _variables.scss // Variables
│ ├── _functions.scss // SASS functions
│ ├── _mixins.scss // SASS mixins
│ └── _placeholders.scss // SASS placeholders
│
├── base/
│ ├── _reset.scss // Reset/normalize
│ ├── _typography.scss // Typography rules
│ └── _base.scss // Base element styles
│
├── components/
│ ├── _buttons.scss // Button styles
│ ├── _cards.scss // Card component
│ ├── _forms.scss // Form styles
│ └── _navbar.scss // Navigation bar
│
├── layout/
│ ├── _header.scss // Header styles
│ ├── _footer.scss // Footer styles
│ ├── _sidebar.scss // Sidebar styles
│ └── _grid.scss // Grid system
│
├── pages/
│ ├── _home.scss // Home page specific styles
│ ├── _about.scss // About page styles
│ └── _contact.scss // Contact page styles
│
├── themes/
│ ├── _dark.scss // Dark theme
│ └── _light.scss // Light theme
│
├── vendors/
│ ├── _bootstrap.scss // Bootstrap overrides
│ └── _jquery-ui.scss // jQuery UI customization
│
└── main.scss // Main file that imports everything
Main File Structure
// main.scss
// This is the main file that imports all partials
@charset "UTF-8";
// 1. Configuration and helpers
@import "abstracts/variables";
@import "abstracts/functions";
@import "abstracts/mixins";
@import "abstracts/placeholders";
// 2. Vendors
@import "vendors/bootstrap";
@import "vendors/jquery-ui";
// 3. Base stuff
@import "base/reset";
@import "base/typography";
@import "base/base";
// 4. Layout-related sections
@import "layout/header";
@import "layout/footer";
@import "layout/sidebar";
@import "layout/grid";
// 5. Components
@import "components/buttons";
@import "components/cards";
@import "components/forms";
@import "components/navbar";
// 6. Page-specific styles
@import "pages/home";
@import "pages/about";
@import "pages/contact";
// 7. Themes
@import "themes/dark";
@import "themes/light";
Common Partial Examples
_mixins.scss - Common Mixins
// _mixins.scss
// Flexbox center
@mixin flex-center {
display: flex;
justify-content: center;
align-items: center;
}
// Media query mixin
@mixin responsive($breakpoint) {
@if $breakpoint == mobile {
@media (max-width: 480px) { @content; }
}
@else if $breakpoint == tablet {
@media (max-width: 768px) { @content; }
}
@else if $breakpoint == desktop {
@media (min-width: 1024px) { @content; }
}
}
// Transition mixin
@mixin transition($properties...) {
transition: $properties;
-webkit-transition: $properties;
-moz-transition: $properties;
}
_base.scss - Base Element Styles
// _base.scss
// Must be imported after _variables.scss
*, *::before, *::after {
box-sizing: border-box;
}
body {
font-family: $font-family;
font-size: $base-font-size;
line-height: $line-height;
color: $text-color;
background-color: $bg-color;
margin: 0;
padding: 0;
}
a {
color: $link-color;
text-decoration: none;
transition: color 0.3s ease;
&:hover {
color: $link-hover-color;
}
}
img {
max-width: 100%;
height: auto;
display: block;
}
ul, ol {
margin: 0;
padding: 0;
list-style: none;
}
_buttons.scss - Button Component
// _buttons.scss
// Component partial for button styles
.btn {
display: inline-block;
padding: $spacing-medium $spacing-large;
border: none;
border-radius: 4px;
font-size: $base-font-size;
font-weight: 600;
text-align: center;
cursor: pointer;
transition: all 0.3s ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}
&--primary {
background: $primary-color;
color: white;
&:hover {
background: darken($primary-color, 10%);
}
}
&--secondary {
background: $secondary-color;
color: white;
&:hover {
background: darken($secondary-color, 10%);
}
}
&--large {
padding: $spacing-large ($spacing-large * 1.5);
font-size: $base-font-size * 1.2;
}
&--small {
padding: $spacing-small $spacing-medium;
font-size: $base-font-size * 0.875;
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
pointer-events: none;
}
}
Problems with @import
While @import has been the standard way to include SASS files for years, it has several significant problems that led to the development of a new module system.
- Global Scope: All variables, mixins, and functions are global, leading to naming conflicts
- Duplicate Imports: Files can be imported multiple times, causing code duplication
- No Namespacing: Everything shares the same namespace, making it hard to track where things come from
- Performance: Large projects can have slow compilation times due to repeated imports
- Dependency Tracking: Difficult to know which files depend on which variables/mixins
Example: Global Scope Problem
// _config-a.scss
$color: blue;
// _config-b.scss
$color: red; // This overwrites the previous $color!
// main.scss
@import "config-a";
@import "config-b";
.element {
color: $color; // Will be red, not blue!
}
Example: Duplicate Import Problem
// _variables.scss
$primary: blue;
// _buttons.scss
@import "variables";
.btn { color: $primary; }
// _forms.scss
@import "variables";
.input { border-color: $primary; }
// main.scss
@import "buttons"; // imports variables
@import "forms"; // imports variables AGAIN!
// Result: _variables.scss is processed twice,
// potentially causing issues and slower compilation
Why @import is Being Deprecated
Due to these problems, the SASS team introduced a new module system with @use and @forward directives. The @import directive is now deprecated and will eventually be removed from SASS. Modern SASS projects should use @use instead.
When to Use @import (Legacy Code)
While @import is deprecated, you may encounter it in:
- Older codebases that haven't been migrated yet
- Legacy third-party libraries that still use @import
- When you need to maintain backward compatibility
For new projects, always prefer @use over @import. We'll cover the modern module system with @use and @forward in the next lesson.
Best Practices for Organizing Partials
- One Component Per File: Each partial should contain styles for one component or concept
- Logical Grouping: Group related partials in folders (components/, layout/, etc.)
- Clear Naming: Use descriptive names that indicate the content (_nav-main.scss, not _n.scss)
- Configuration First: Always import variables and functions before other files
- Utilities Last: Import utility classes last so they can override other styles
- Document Dependencies: Add comments in partials indicating what they depend on
- Keep Partials Focused: Each file should have a single responsibility
Documented Partial Example
// _cards.scss
// Card component styles
//
// Dependencies:
// - abstracts/variables (colors, spacing)
// - abstracts/mixins (responsive mixin)
//
// Usage:
// <div class="card">
// <div class="card__header">...</div>
// <div class="card__body">...</div>
// </div>
.card {
background: $card-bg;
border-radius: $border-radius;
box-shadow: $shadow-light;
overflow: hidden;
&__header {
padding: $spacing-medium;
border-bottom: 1px solid $border-color;
}
&__body {
padding: $spacing-medium;
}
@include responsive(mobile) {
margin: $spacing-small;
}
}
Real-World Project Structure
Complete Project Example
// Project structure for a blog website
blog-project/
├── sass/
│ ├── abstracts/
│ │ ├── _variables.scss
│ │ ├── _mixins.scss
│ │ └── _functions.scss
│ │
│ ├── base/
│ │ ├── _reset.scss
│ │ ├── _typography.scss
│ │ └── _utilities.scss
│ │
│ ├── layout/
│ │ ├── _header.scss
│ │ ├── _nav.scss
│ │ ├── _sidebar.scss
│ │ ├── _footer.scss
│ │ └── _grid.scss
│ │
│ ├── components/
│ │ ├── _buttons.scss
│ │ ├── _cards.scss
│ │ ├── _forms.scss
│ │ ├── _post.scss
│ │ ├── _comment.scss
│ │ └── _pagination.scss
│ │
│ ├── pages/
│ │ ├── _home.scss
│ │ ├── _blog-list.scss
│ │ ├── _blog-post.scss
│ │ └── _contact.scss
│ │
│ └── main.scss
│
└── css/
└── main.css (compiled output)
// main.scss content:
@import "abstracts/variables";
@import "abstracts/functions";
@import "abstracts/mixins";
@import "base/reset";
@import "base/typography";
@import "base/utilities";
@import "layout/header";
@import "layout/nav";
@import "layout/sidebar";
@import "layout/footer";
@import "layout/grid";
@import "components/buttons";
@import "components/cards";
@import "components/forms";
@import "components/post";
@import "components/comment";
@import "components/pagination";
@import "pages/home";
@import "pages/blog-list";
@import "pages/blog-post";
@import "pages/contact";
Exercise 1: Create a Modular Button System
Create a partial file structure for a button system:
- Create _variables.scss with color and spacing variables
- Create _mixins.scss with a button-variant mixin
- Create _buttons.scss that uses the variables and mixins
- Create main.scss that imports all three partials in the correct order
- Test that the compilation works correctly
Exercise 2: Organize a Project
Set up a complete project structure using the 7-1 pattern:
- Create the folder structure with all 7 folders
- Create at least 2 partials in each folder
- Create a main.scss file that imports everything in the correct order
- Add comments documenting what each section does
- Ensure variables are defined before they're used
Exercise 3: Debug Import Order Issues
Given this broken code, fix the import order:
// main.scss (BROKEN)
@import "components/buttons";
@import "base/typography";
@import "abstracts/variables";
@import "layout/header";
@import "abstracts/mixins";
// Fix the order so that:
// 1. Variables and mixins are available to all other files
// 2. Base styles come before components
// 3. Layout comes after base but before page-specific styles