SCSS File Organization and Import Strategies

1. Partial Files (_filename.scss) and Underscore Convention

Pattern Naming Description Purpose
Partial file _filename.scss Underscore prefix Not compiled standalone
Main file main.scss No underscore Entry point, compiled
@use partial @use 'filename' Omit underscore and .scss Modern import
@import partial @import 'filename' Legacy import (deprecated) Avoid in new code
Variables partial _variables.scss Global variables Shared configuration
Mixins partial _mixins.scss Reusable mixins Shared utilities

Example: Partial files organization

// File structure
scss/
├── main.scss              // Entry point (compiled)
├── _variables.scss        // Partial (not compiled)
├── _mixins.scss           // Partial
├── _functions.scss        // Partial
└── _reset.scss            // Partial

// _variables.scss (partial)
// This file won't be compiled to CSS on its own
$primary-color: #007bff;
$secondary-color: #6c757d;
$font-stack: 'Helvetica', Arial, sans-serif;
$spacing-unit: 8px;

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

@mixin responsive-font($min, $max) {
  font-size: clamp(#{$min}, 2.5vw, #{$max});
}

// _functions.scss (partial)
@use 'sass:math';

@function spacing($multiplier) {
  @return $spacing-unit * $multiplier;
}

// main.scss (entry point - will be compiled)
// Modern approach with @use
@use 'variables' as vars;
@use 'mixins' as mx;
@use 'functions' as fn;
@use 'reset';

// Now use the imported modules
.container {
  color: vars.$primary-color;
  padding: fn.spacing(2);  // 16px
  
  @include mx.flex-center;
}

// Legacy approach with @import (DEPRECATED)
// @import 'variables';
// @import 'mixins';
// @import 'functions';
// @import 'reset';

// Naming conventions
scss/
├── _btn-primary.scss      // Component partial
├── _btn-secondary.scss
├── _card-default.scss
├── _card-featured.scss
└── buttons.scss           // Compiled: imports all btn-* partials

// buttons.scss
@use 'btn-primary';
@use 'btn-secondary';

// Partial with configuration
// _button.scss
$-default-padding: 10px 20px !default;  // Private variable
$button-radius: 4px !default;           // Public variable

.button {
  padding: $-default-padding;
  border-radius: $button-radius;
}

// Using configured partial
@use 'button' with (
  $button-radius: 8px
);

// Multiple partials in subdirectories
scss/
├── base/
│   ├── _reset.scss
│   ├── _typography.scss
│   └── _variables.scss
├── components/
│   ├── _buttons.scss
│   ├── _cards.scss
│   └── _forms.scss
└── main.scss

// main.scss
@use 'base/variables';
@use 'base/reset';
@use 'base/typography';
@use 'components/buttons';
@use 'components/cards';
@use 'components/forms';
Note: Partials (files starting with _) are not compiled to CSS files directly. They must be imported into a main file that doesn't have an underscore.

2. Import Order (@use order) and Dependency Management

Order Category Files Reason
1st Configuration Variables, functions Used by everything
2nd Utilities Mixins, helpers Reusable tools
3rd Base/Reset Normalize, reset, typography Foundation styles
4th Layout Grid, containers Page structure
5th Components Buttons, cards, forms UI elements
6th Pages Page-specific styles Specific overrides
7th Themes Dark mode, variants Theme overrides
8th Utilities Helper classes Highest specificity

Example: Proper import order

// main.scss - Correct import order

// 1. Configuration (variables must come first)
@use 'config/variables' as vars;
@use 'config/functions' as fn;

// 2. Utilities (mixins use variables)
@use 'utilities/mixins' as mx;
@use 'utilities/helpers';

// 3. Vendors/Third-party (before base styles)
@use 'vendors/normalize';
@use 'vendors/bootstrap-grid';

// 4. Base styles (foundation)
@use 'base/reset';
@use 'base/typography';
@use 'base/forms';

// 5. Layout (structural elements)
@use 'layout/grid';
@use 'layout/header';
@use 'layout/footer';
@use 'layout/sidebar';

// 6. Components (UI elements)
@use 'components/buttons';
@use 'components/cards';
@use 'components/modals';
@use 'components/navigation';
@use 'components/forms';

// 7. Pages (page-specific styles)
@use 'pages/home';
@use 'pages/about';
@use 'pages/contact';

// 8. Themes (variants and modes)
@use 'themes/dark';
@use 'themes/high-contrast';

// 9. Utilities (override everything)
@use 'utilities/spacing';
@use 'utilities/text';
@use 'utilities/display';

// Dependency example - WRONG order
// @use 'components/buttons';  // Uses variables
// @use 'config/variables';    // Defined after use - ERROR!

// Dependency example - CORRECT order
@use 'config/variables';
@use 'components/buttons';  // Now variables are available

// Namespace management
@use 'config/variables' as v;
@use 'utilities/mixins' as m;
@use 'utilities/functions' as f;

.container {
  color: v.$primary;
  padding: f.spacing(2);
  @include m.flex-center;
}

// Avoiding namespace with *
@use 'config/variables' as *;

.button {
  // No prefix needed
  background: $primary-color;
  padding: $spacing-unit * 2;
}

// Dependency tree example
// _variables.scss (no dependencies)
$primary: blue;

// _functions.scss (depends on variables)
@use 'variables' as vars;

@function get-primary() {
  @return vars.$primary;
}

// _mixins.scss (depends on functions and variables)
@use 'variables' as vars;
@use 'functions' as fn;

@mixin primary-button {
  background: fn.get-primary();
  padding: vars.$spacing-unit;
}

// _buttons.scss (depends on mixins)
@use 'mixins' as mx;

.button {
  @include mx.primary-button;
}

// Conditional imports based on environment
$environment: 'production' !default;

@if $environment == 'development' {
  @use 'dev/debug';
  @use 'dev/grid-overlay';
} @else if $environment == 'production' {
  @use 'prod/optimized';
}

// Import with configuration
@use 'config/variables' with (
  $primary-color: #ff0000,
  $font-size: 18px
);

// Forward for re-exporting (create API)
// _index.scss in utilities/
@forward 'mixins';
@forward 'functions';
@forward 'helpers';

// main.scss
@use 'utilities';  // Gets all forwarded items

3. File Structure Patterns (7-1 Architecture, ITCSS)

Folder Purpose Example Files Description
abstracts/ Variables, mixins, functions _variables.scss, _mixins.scss No CSS output
base/ Resets, typography, base _reset.scss, _typography.scss Foundation styles
components/ UI components _button.scss, _card.scss Reusable components
layout/ Page structure _header.scss, _grid.scss Major sections
pages/ Page-specific styles _home.scss, _about.scss Per-page overrides
themes/ Theme variations _dark.scss, _admin.scss Theme switches
vendors/ Third-party CSS _normalize.scss, _bootstrap.scss External libraries

Example: 7-1 Architecture pattern

// Complete 7-1 folder structure
scss/
├── abstracts/
│   ├── _variables.scss     // Global variables
│   ├── _functions.scss     // Sass functions
│   ├── _mixins.scss        // Sass mixins
│   └── _placeholders.scss  // Sass placeholders
├── base/
│   ├── _reset.scss         // Reset/normalize
│   ├── _typography.scss    // Typography rules
│   ├── _animations.scss    // Keyframes
│   └── _utilities.scss     // Utility classes
├── components/
│   ├── _buttons.scss       // Button styles
│   ├── _cards.scss         // Card component
│   ├── _carousel.scss      // Carousel
│   ├── _dropdown.scss      // Dropdown
│   ├── _forms.scss         // Form elements
│   ├── _modal.scss         // Modal dialog
│   ├── _navigation.scss    // Navigation
│   └── _table.scss         // Tables
├── layout/
│   ├── _grid.scss          // Grid system
│   ├── _header.scss        // Header
│   ├── _footer.scss        // Footer
│   ├── _sidebar.scss       // Sidebar
│   └── _containers.scss    // Containers
├── pages/
│   ├── _home.scss          // Home page
│   ├── _about.scss         // About page
│   ├── _contact.scss       // Contact page
│   └── _dashboard.scss     // Dashboard
├── themes/
│   ├── _dark.scss          // Dark theme
│   ├── _light.scss         // Light theme
│   └── _admin.scss         // Admin theme
├── vendors/
│   ├── _normalize.scss     // Normalize.css
│   └── _bootstrap.scss     // Bootstrap subset
└── main.scss               // Main entry file

// main.scss - The "1" file in 7-1
@charset 'utf-8';

// 1. Abstracts
@use 'abstracts/variables' as vars;
@use 'abstracts/functions' as fn;
@use 'abstracts/mixins' as mx;
@use 'abstracts/placeholders';

// 2. Vendors
@use 'vendors/normalize';

// 3. Base
@use 'base/reset';
@use 'base/typography';
@use 'base/animations';
@use 'base/utilities';

// 4. Layout
@use 'layout/grid';
@use 'layout/header';
@use 'layout/footer';
@use 'layout/sidebar';
@use 'layout/containers';

// 5. Components
@use 'components/buttons';
@use 'components/cards';
@use 'components/carousel';
@use 'components/dropdown';
@use 'components/forms';
@use 'components/modal';
@use 'components/navigation';
@use 'components/table';

// 6. Pages
@use 'pages/home';
@use 'pages/about';
@use 'pages/contact';
@use 'pages/dashboard';

// 7. Themes
@use 'themes/dark';
@use 'themes/light';

// Alternative: Atomic Design structure
scss/
├── 00-settings/
│   └── _variables.scss
├── 01-tools/
│   ├── _functions.scss
│   └── _mixins.scss
├── 02-generic/
│   └── _normalize.scss
├── 03-elements/
│   ├── _headings.scss
│   └── _links.scss
├── 04-objects/
│   ├── _container.scss
│   └── _grid.scss
├── 05-components/
│   ├── _button.scss
│   └── _card.scss
├── 06-utilities/
│   └── _spacing.scss
└── main.scss

// Alternative: Component-based structure (React/Vue)
src/
├── components/
│   ├── Button/
│   │   ├── Button.tsx
│   │   ├── Button.scss
│   │   └── index.ts
│   ├── Card/
│   │   ├── Card.tsx
│   │   ├── Card.scss
│   │   └── index.ts
│   └── ...
├── styles/
│   ├── abstracts/
│   ├── base/
│   └── global.scss
└── App.scss

// Alternative: Feature-based structure
scss/
├── core/               // Shared across features
│   ├── _variables.scss
│   ├── _mixins.scss
│   └── _base.scss
├── features/
│   ├── auth/
│   │   ├── _login.scss
│   │   └── _register.scss
│   ├── dashboard/
│   │   ├── _widgets.scss
│   │   └── _charts.scss
│   └── products/
│       ├── _list.scss
│       └── _detail.scss
└── main.scss

// Minimal structure (small projects)
scss/
├── _variables.scss
├── _mixins.scss
├── _base.scss
├── _layout.scss
├── _components.scss
└── main.scss

4. Index Files (_index.scss) and Barrel Exports

Pattern Syntax Purpose Benefit
Index file _index.scss Folder entry point Clean imports
@forward @forward 'file' Re-export module Create public API
@use 'folder' Import index Auto-loads _index.scss Shorter paths
Prefix stripping @forward ... hide $-private Hide private members Encapsulation
Namespace @forward ... as name-* Add prefix Avoid conflicts

Example: Index files and barrel patterns

// Folder structure with index files
components/
├── _index.scss         // Barrel export
├── _button.scss
├── _card.scss
└── _modal.scss

// components/_index.scss
// Forward all components from this folder
@forward 'button';
@forward 'card';
@forward 'modal';

// main.scss
// Instead of importing each component:
// @use 'components/button';
// @use 'components/card';
// @use 'components/modal';

// Just import the index:
@use 'components';

// Advanced: Selective forwarding
// components/_index.scss
@forward 'button';
@forward 'card';
// Don't forward modal (keep it private to components)

// Advanced: Forward with prefix
// components/_index.scss
@forward 'button' as btn-*;
@forward 'card' as card-*;

// Usage
@use 'components' as c;

.element {
  @include c.btn-primary;
  @include c.card-layout;
}

// Advanced: Forward with hiding
// abstracts/_variables.scss
$primary: blue;
$-internal-spacing: 8px;  // Private (starts with -)

// abstracts/_index.scss
@forward 'variables' hide $-internal-spacing;

// main.scss
@use 'abstracts' as abs;

.button {
  color: abs.$primary;           // ✓ Works
  // padding: abs.$-internal-spacing;  // ✗ Error: private
}

// Nested index files
scss/
├── base/
│   ├── _index.scss
│   ├── _reset.scss
│   └── _typography.scss
├── components/
│   ├── _index.scss
│   ├── buttons/
│   │   ├── _index.scss
│   │   ├── _primary.scss
│   │   └── _secondary.scss
│   └── cards/
│       ├── _index.scss
│       ├── _default.scss
│       └── _featured.scss
└── main.scss

// components/buttons/_index.scss
@forward 'primary';
@forward 'secondary';

// components/cards/_index.scss
@forward 'default';
@forward 'featured';

// components/_index.scss
@forward 'buttons';
@forward 'cards';

// main.scss
@use 'components';  // Gets everything!

// Practical: Theme API with index
themes/
├── _index.scss
├── _dark.scss
├── _light.scss
└── _high-contrast.scss

// themes/_index.scss
@forward 'dark' as dark-*;
@forward 'light' as light-*;
@forward 'high-contrast' as hc-*;

// Or selective theme forwarding
$active-theme: 'dark' !default;

@if $active-theme == 'dark' {
  @forward 'dark';
} @else if $active-theme == 'light' {
  @forward 'light';
} @else {
  @forward 'high-contrast';
}

// Practical: Utilities barrel
utilities/
├── _index.scss
├── _spacing.scss
├── _text.scss
├── _colors.scss
└── _display.scss

// utilities/_index.scss
@forward 'spacing';
@forward 'text';
@forward 'colors';
@forward 'display';

// Configuration through index
// config/_index.scss
@forward 'variables' with (
  $primary: #007bff !default,
  $spacing: 8px !default
);
@forward 'functions';
@forward 'mixins';

// main.scss
@use 'config' with (
  $primary: #ff0000  // Override default
);

// Multi-level barrel
scss/
├── core/
│   ├── _index.scss
│   ├── abstracts/
│   │   ├── _index.scss
│   │   ├── _variables.scss
│   │   └── _mixins.scss
│   └── base/
│       ├── _index.scss
│       └── _reset.scss
└── main.scss

// core/abstracts/_index.scss
@forward 'variables';
@forward 'mixins';

// core/base/_index.scss
@forward 'reset';

// core/_index.scss
@forward 'abstracts';
@forward 'base';

// main.scss
@use 'core';  // Everything in one import!

5. Dynamic Imports and Conditional @use Loading

Pattern Use Case Example Benefit
@if import Environment-based Dev vs production Conditional loading
Feature flags Toggle features A/B testing Flexible builds
Theme selection Multi-theme apps Dark/light modes Single build
Loop imports Similar files Icon sets, colors DRY imports

Example: Conditional and dynamic imports

// Environment-based imports
$env: 'production' !default;

@if $env == 'development' {
  @use 'dev/debug-grid';
  @use 'dev/component-outline';
  @use 'dev/performance-overlay';
} @else if $env == 'production' {
  @use 'prod/optimized-styles';
}

// Feature flags
$features: (
  animations: true,
  dark-mode: true,
  experimental-grid: false
);

@use 'sass:map';

@if map.get($features, animations) {
  @use 'animations/transitions';
  @use 'animations/keyframes';
}

@if map.get($features, dark-mode) {
  @use 'themes/dark';
}

@if map.get($features, experimental-grid) {
  @use 'experimental/subgrid';
}

// Dynamic theme loading
$active-theme: 'dark' !default;

// Only load the active theme
@if $active-theme == 'dark' {
  @use 'themes/dark';
} @else if $active-theme == 'light' {
  @use 'themes/light';
} @else if $active-theme == 'high-contrast' {
  @use 'themes/high-contrast';
} @else {
  @use 'themes/default';
}

// Browser-specific imports
$target-browser: 'modern' !default;

@if $target-browser == 'legacy' {
  @use 'vendors/normalize';
  @use 'polyfills/flexbox';
  @use 'polyfills/grid';
} @else {
  @use 'modern/reset';
}

// Responsive strategy selection
$responsive-strategy: 'mobile-first' !default;

@if $responsive-strategy == 'mobile-first' {
  @use 'responsive/mobile-first';
} @else if $responsive-strategy == 'desktop-first' {
  @use 'responsive/desktop-first';
} @else {
  @use 'responsive/adaptive';
}

// Import based on configuration
$enable-rtl: false !default;
$enable-print: true !default;

@if $enable-rtl {
  @use 'i18n/rtl';
}

@if $enable-print {
  @use 'print/styles';
}

// Loop-based imports (components)
$component-list: (
  'button',
  'card',
  'modal',
  'dropdown',
  'table'
);

@each $component in $component-list {
  @use 'components/#{$component}';
}

// Conditional utility imports
$utilities: (
  spacing: true,
  text: true,
  colors: false,
  display: true
);

@each $util, $enabled in $utilities {
  @if $enabled {
    @use 'utilities/#{$util}';
  }
}

// Breakpoint-based imports
$breakpoints: (
  sm: 576px,
  md: 768px,
  lg: 992px
);

$active-breakpoints: (sm, md, lg);

@each $bp in $active-breakpoints {
  @use 'responsive/#{$bp}';
}

// Platform-specific imports
$platform: 'web' !default;  // 'web', 'mobile', 'desktop'

@if $platform == 'mobile' {
  @use 'platforms/mobile/touch-optimized';
  @use 'platforms/mobile/gestures';
} @else if $platform == 'desktop' {
  @use 'platforms/desktop/hover-states';
  @use 'platforms/desktop/keyboard-nav';
} @else {
  @use 'platforms/web/standard';
}

// Conditional vendor imports
$include-vendors: (
  normalize: true,
  bootstrap-grid: false,
  animate-css: true
);

@if map.get($include-vendors, normalize) {
  @use 'vendors/normalize';
}

@if map.get($include-vendors, bootstrap-grid) {
  @use 'vendors/bootstrap-grid';
}

@if map.get($include-vendors, animate-css) {
  @use 'vendors/animate';
}

// Build configuration
$build-config: (
  minify: true,
  sourcemaps: true,
  rtl: false,
  themes: (dark, light),
  components: (button, card, modal)
);

// Load themes
@each $theme in map.get($build-config, themes) {
  @use 'themes/#{$theme}';
}

// Load components
@each $component in map.get($build-config, components) {
  @use 'components/#{$component}';
}

6. Glob Patterns and Bulk Imports (with build tools)

Tool Pattern Example Limitation
sass-loader Webpack glob @import '**/*.scss' Build tool required
node-sass includePaths Config option Node.js only
Dart Sass No native glob Manual imports Must use index files
gulp-sass Task runner glob src/**/*.scss External tool

Example: Bulk import strategies

// Note: Sass doesn't support native glob imports
// Must use build tools or index files

// Webpack sass-loader with glob (NOT standard Sass)
// webpack.config.js
module.exports = {
  module: {
    rules: [{
      test: /\.scss$/,
      use: ['style-loader', 'css-loader', 'sass-loader']
    }]
  }
};

// Then in SCSS (with plugins):
// @import 'components/**/*.scss';  // Not standard!

// STANDARD approach: Use index files
// components/_index.scss
@forward 'button';
@forward 'card';
@forward 'modal';
@forward 'dropdown';
// ... etc

// Or generate index programmatically (build script)
// generate-index.js
const fs = require('fs');
const path = require('path');

const componentsDir = './scss/components';
const files = fs.readdirSync(componentsDir)
  .filter(f => f.endsWith('.scss') && !f.startsWith('_index'))
  .map(f => f.replace('.scss', ''));

const indexContent = files
  .map(f => `@forward '${f}';`)
  .join('\n');

fs.writeFileSync(
  path.join(componentsDir, '_index.scss'),
  indexContent
);

// Gulp task for automatic index generation
// gulpfile.js
const gulp = require('gulp');
const concat = require('gulp-concat');

gulp.task('generate-imports', () => {
  return gulp.src('scss/components/_*.scss')
    .pipe(/* generate @forward statements */)
    .pipe(concat('_index.scss'))
    .pipe(gulp.dest('scss/components/'));
});

// Manual bulk import pattern (repetitive but clear)
// components/_index.scss
@forward 'button';
@forward 'button-group';
@forward 'button-toolbar';
@forward 'card';
@forward 'card-header';
@forward 'card-body';
@forward 'card-footer';
@forward 'modal';
@forward 'modal-dialog';
@forward 'dropdown';
@forward 'dropdown-menu';
@forward 'tooltip';
@forward 'popover';

// Alternative: Programmatic import helper
// _import-helper.scss
@use 'sass:meta';
@use 'sass:list';

@mixin import-all($folder, $files...) {
  @each $file in $files {
    // This doesn't actually work in Sass
    // Just showing the concept
    // @use '#{$folder}/#{$file}';
  }
}

// Vite glob imports (JavaScript side)
// main.ts
const modules = import.meta.glob('./styles/**/*.scss');

// Parcel glob (automatic)
// Just import the folder
@use 'components';  // Parcel handles the rest

// Best practice: Organized manual imports
// _all.scss (common pattern)
// Base
@forward 'base/reset';
@forward 'base/typography';
@forward 'base/forms';

// Layout
@forward 'layout/grid';
@forward 'layout/container';
@forward 'layout/header';
@forward 'layout/footer';

// Components (alphabetical for easy maintenance)
@forward 'components/alert';
@forward 'components/badge';
@forward 'components/breadcrumb';
@forward 'components/button';
@forward 'components/card';
@forward 'components/carousel';
@forward 'components/dropdown';
@forward 'components/modal';
@forward 'components/navbar';
@forward 'components/pagination';
@forward 'components/progress';
@forward 'components/spinner';
@forward 'components/table';
@forward 'components/tabs';
@forward 'components/tooltip';

// Node script to generate imports
// scripts/generate-sass-index.mjs
import { readdirSync, writeFileSync } from 'fs';
import { join, basename } from 'path';

function generateIndex(dir) {
  const files = readdirSync(dir)
    .filter(f => f.endsWith('.scss') && f !== '_index.scss')
    .map(f => basename(f, '.scss'))
    .filter(f => !f.startsWith('_index'));
  
  const imports = files
    .map(f => `@forward '${f}';`)
    .join('\n');
  
  writeFileSync(
    join(dir, '_index.scss'),
    `// Auto-generated - do not edit\n${imports}\n`
  );
}

generateIndex('./scss/components');
generateIndex('./scss/utilities');

// Package.json script
{
  "scripts": {
    "sass:index": "node scripts/generate-sass-index.mjs",
    "sass:build": "npm run sass:index && sass src/main.scss dist/styles.css"
  }
}

File Organization Summary

  • Partials: Use _filename.scss for files that shouldn't compile standalone
  • Import order: Config → Utils → Base → Layout → Components → Pages → Themes → Utilities
  • 7-1 Pattern: 7 folders + 1 main file for large projects
  • Index files: Use _index.scss with @forward for barrel exports
  • Conditional: Use @if for environment/feature-based imports
  • No glob: Sass has no native glob; use index files or build scripts
  • Modern approach: @use and @forward over deprecated @import
Warning: @import is deprecated. Use @use for importing and @forward for re-exporting. Migration is essential for Dart Sass 2.0.