Folder Architecture (7-1 Pattern)
A ten-line stylesheet needs no structure. A real website with a header, footer, forms, twenty components and three page layouts does. Without a plan, styles end up wherever someone typed them, and nobody knows where to add the next rule. Sass partials and modules let you split styles into many small files; a folder architecture decides where each file goes.
In this lesson you will learn the popular 7-1 pattern (seven folders, one entry file), adapt it to the modern @use and @forward module system, and see how to combine it with CSS cascade layers.
The 7-1 pattern
The 7-1 pattern is a community convention, popularised by the Sass Guidelines project, not a rule of the Sass language. It groups partials by their role:
| Folder | Holds | Outputs CSS? |
|---|---|---|
abstracts/ | Variables, functions, mixins, placeholders | No |
vendors/ | Third-party CSS you do not edit | Yes |
base/ | Reset, typography, element defaults (body, a, h1) | Yes |
layout/ | Big page regions: header, footer, grid, sidebar | Yes |
components/ | Small reusable pieces: buttons, cards, badges, modals | Yes |
pages/ | Styles for one specific page, such as the home hero | Yes |
themes/ | Alternative themes, such as a dark or festive theme | Yes |
Plus one entry file, main.scss, which loads everything in a sensible order. The full tree for a Rohtak coaching institute's site might look like this:
scss/
abstracts/
_variables.scss
_functions.scss
_mixins.scss
_index.scss
vendors/
_normalize.scss
base/
_reset.scss
_typography.scss
_index.scss
layout/
_header.scss
_footer.scss
_grid.scss
_index.scss
components/
_button.scss
_card.scss
_course-badge.scss
_index.scss
pages/
_home.scss
_admissions.scss
_index.scss
themes/
_dark.scss
main.scssYou do not need all seven folders on day one. A small site might use only abstracts, base, layout and components. Add folders when they would hold more than one file.
Wiring it up with modules
The original 7-1 pattern was written for @import, where the entry file imported abstracts first and everything else could "see" them. With the module system, each file loads what it needs instead. Two rules make it work:
abstracts/produces no CSS, and its_index.scssuses@forwardto offer every variable, function and mixin through one name.- Every other partial that needs a variable or mixin starts with
@use "../abstracts".
// abstracts/_index.scss
@forward "variables";
@forward "mixins";
// abstracts/_variables.scss
$brand: #0e7490 !default;
$radius: 6px !default;
// abstracts/_mixins.scss
@use "variables";
@mixin card-surface {
background: white;
border-radius: variables.$radius;
}
// components/_card.scss
@use "../abstracts" as a;
.card {
@include a.card-surface;
padding: 1rem;
}
// layout/_header.scss
@use "../abstracts" as a;
.site-header {
background: a.$brand;
color: white;
padding: 1rem;
}Each CSS-producing folder has an _index.scss that simply loads its files, for example components/_index.scss contains @use "card"; and one line per component. The entry file then stays very short, and it is the one place where the abstracts are configured:
// main.scss
@use "abstracts" with ($brand: #cc6699);
@use "base";
@use "layout";
@use "components";
@use "pages";Compiled, the output follows the order of the @use lines: reset and typography first, then layout, components and pages:
*, *::before, *::after {
box-sizing: border-box;
}
body {
margin: 0;
}
body {
font-family: system-ui, sans-serif;
color: #1f2937;
}
a {
color: #cc6699;
}
.site-header {
background: #cc6699;
color: white;
padding: 1rem;
}
.card {
background: white;
border-radius: 6px;
padding: 1rem;
}
.home-hero {
min-height: 60vh;
}Notice that $brand became pink everywhere, even in layout/_header.scss, because main.scss configured the abstracts module first, and a module is loaded only once. That is why the configured @use must be the first line.
Why the order matters
The order goes from general to specific: element defaults, then large layout regions, then components, then page-specific overrides. Later rules win when specificity is equal, so a page file can adjust a component without !important.
You can make that order explicit with cascade layers (see Cascade Layers). @use cannot go inside @layer, but the meta.load-css() mixin can:
// main.scss with cascade layers
@use "sass:meta";
@use "abstracts" with ($brand: #cc6699);
@layer base, layout, components, pages;
@layer base { @include meta.load-css("base"); }
@layer layout { @include meta.load-css("layout"); }
@layer components { @include meta.load-css("components"); }
@layer pages { @include meta.load-css("pages"); }Now even a page rule with low specificity beats a component rule, because the pages layer is declared later. The configured @use "abstracts" at the top still reaches every layer: when layout/_header.scss loads the abstracts, Sass reuses the module that is already loaded, with its pink $brand.
A small preview
The editor on this site compiles one file, but you can still see the idea of "abstracts first, then general, then specific" in a single file:
// abstracts
$brand: #cc6699;
@mixin card-surface { background: white; border-radius: 6px; }
// base
body { margin: 0; font-family: system-ui, sans-serif; }
// layout
.site-header { background: $brand; color: white; padding: 1rem; }
// components
.card { @include card-surface; padding: 1rem; }
// pages
.page-admissions .card { border: 2px solid $brand; }body {
margin: 0;
font-family: system-ui, sans-serif;
}
.site-header {
background: #cc6699;
color: white;
padding: 1rem;
}
.card {
background: white;
border-radius: 6px;
padding: 1rem;
}
.page-admissions .card {
border: 2px solid #cc6699;
}Common mistakes
- Putting CSS rules in
abstracts/. Every file loads the abstracts, so readers expect them to output nothing. A style rule hidden there is hard to find and lands at an unexpected place in the CSS order. - Configuring abstracts after another file loaded them. The configured
@usemust come first inmain.scss. - Huge component files. One component per file keeps changes small and reviews easy.
- Copying all seven folders for a tiny site. Start with what you need; the structure should help, not slow you down.
Key points
- The 7-1 pattern groups partials into abstracts, vendors, base, layout, components, pages and themes, plus one
main.scss. abstracts/holds variables, functions and mixins only, forwarded through an_index.scss.- With modules, each partial loads
../abstractsitself;main.scssconfigures abstracts first and then loads each folder. - Order folders from general to specific; cascade layers with
meta.load-css()can make that order explicit. - Adapt the pattern to the project size; it is a convention, not a rule.
Exercise
Plan the Sass folders for a Kochi homestay website with a header, footer, room cards, a booking form, a gallery page and a monsoon theme. Write the folder tree, the content of components/_index.scss, and a main.scss that configures $brand: #15803d in the abstracts and loads every folder in the right order.
Show solution
scss/
abstracts/ _variables.scss _mixins.scss _index.scss
base/ _reset.scss _typography.scss _index.scss
layout/ _header.scss _footer.scss _index.scss
components/ _room-card.scss _booking-form.scss _index.scss
pages/ _gallery.scss _index.scss
themes/ _monsoon.scss
main.scss// components/_index.scss
@use "room-card";
@use "booking-form";
// main.scss
@use "abstracts" with ($brand: #15803d);
@use "base";
@use "layout";
@use "components";
@use "pages";The monsoon theme is not loaded by default; it can be compiled separately or loaded under a class with meta.load-css("themes/monsoon").
Quick Quiz
1. Which folder should contain only variables, functions and mixins?
Abstracts produce no CSS, so every file can load them safely.
2. With @use, how does components/_card.scss get the brand colour?
In the module system each file declares its own dependencies.
3. Why must @use "abstracts" with (...) be the first line of main.scss?
If another file loads the module first, it is too late to configure it.
4. How can you put a whole folder's CSS inside a cascade layer?
@use must be at the top of a file, but meta.load-css() can be included inside @layer.
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
