Organiser ses fichiers SCSS : architecture 7-1
Dossiers, partials, @use et @forward : une architecture SCSS claire, inspirée du modèle 7-1, pour retrouver chaque style et éviter @import, déprécié dans Dart Sass.

Dossiers, partials, @use et @forward : une architecture SCSS claire, inspirée du modèle 7-1, pour retrouver chaque style et éviter @import, déprécié dans Dart Sass.

Votre feuille de style grossit, les variables deviennent introuvables, deux composants se marchent dessus et personne ne sait plus où ajouter une règle. Le problème vient rarement de Sass lui-même : il vient de l’organisation des fichiers. Ce guide vous donne une structure claire, inspirée du modèle 7-1, avec le système de modules moderne de Sass (@use et @forward) plutôt que @import, déprécié dans Dart Sass.
Public visé : développeurs et développeuses qui connaissent déjà les variables et l’imbrication en SCSS, et qui veulent une convention partagée par toute l’équipe.
Organiser du SCSS revient à répondre à trois questions, et à y répondre de la même façon dans tout le projet :
La réponse courte :
abstracts/ qui ne produit aucun CSS ;base/ ;layout/, les briques réutilisables dans components/, les exceptions dans pages/ ;main.scss, assemble le tout avec @use, dans un ordre voulu.Le navigateur ne reçoit que du CSS compilé. L’architecture SCSS n’existe que pour les humains et pour le build : si elle ne facilite ni la relecture de code ni l’arrivée d’un nouveau contributeur, elle est trop compliquée.
Le modèle 7-1 est un gabarit répandu, popularisé par les « Sass Guidelines » de Hugo Giraudel : sept dossiers de partials et un seul fichier qui les assemble. Voici l’arborescence, avec les dossiers qui ne produisent aucun CSS (les outils) séparés de ceux qui en produisent :
styles/
abstracts/ # variables, fonctions, mixins : aucun CSS généré
_index.scss
_tokens.scss
_mixins.scss
vendors/ # styles de bibliothèques tierces
base/ # réinitialisation, typographie, éléments HTML
layout/ # en-tête, pied de page, grille, conteneurs
components/ # boutons, cartes, formulaires, modales
pages/ # styles vraiment propres à une page
themes/ # variantes (clair, sombre, marque)
main.scss # le « 1 » : point d’entrée unique
Les noms peuvent varier d’une équipe à l’autre (helpers ou utils à la place d’abstracts, par exemple). Ce qui compte, c’est de séparer les valeurs, le générique, les composants et les exceptions.
Le 7-1 est un point de départ, pas un dogme. Un petit site n’a pas besoin de sept dossiers dont la moitié resterait vide. Commencez avec abstracts/, base/, components/ et main.scss, puis ajoutez layout/, pages/ ou themes/ le jour où le besoin se fait sentir. Une structure qui grandit avec le projet vaut mieux qu’une structure complète mais déserte.
Les feuilles de style se lisent de haut en bas : à spécificité égale, la dernière règle gagne. Un ordre cohérent consiste à aller du plus générique au plus spécifique : vendors, base, layout, components, pages, themes. Si vous avez des classes utilitaires (marges, texte réservé aux lecteurs d’écran), placez-les en dernier pour qu’elles puissent surcharger un composant sans artifice.
main.scss avec @useLe fichier d’entrée ne contient aucun style : il se contente d’assembler. Avec @use, l’ordre des règles correspond à l’ordre du CSS généré.
// main.scss : assemble, ne stylise pas
@use 'vendors';
@use 'base';
@use 'layout';
@use 'components';
@use 'pages';
@use 'themes';
Chaque dossier expose un fichier _index.scss. Quand vous écrivez @use 'base', Sass charge automatiquement base/_index.scss, qui renvoie vers les partials du dossier avec @forward :
// base/_index.scss
@forward 'reset';
@forward 'typography';
Le dossier abstracts/ n’apparaît pas dans main.scss, car il ne génère pas de CSS : ce sont les fichiers qui ont besoin de ses valeurs qui le chargent eux-mêmes. Cette règle simple évite d’inclure par erreur du CSS « visible » dans une couche censée n’être qu’une boîte à outils.
@use, @forward et @import : ce qui change@importLa documentation officielle de Sass indique que, depuis Dart Sass 1.80.0, la règle @import est dépréciée et qu’elle sera retirée du langage dans Dart Sass 3.0.0. Elle recommande de lui préférer @use. Parmi les défauts listés, @import rend tout accessible globalement (impossible de savoir d’où vient une variable), oblige les bibliothèques à préfixer tous leurs noms, et évalue puis réémet le CSS d’un fichier à chaque import. Vous trouverez le détail dans la documentation de @import.
Le système de modules corrige ces points :
@use ne rend les membres disponibles que dans le fichier courant ;tokens.$bleu, pas $bleu ;- ou _ restent privés au module.Deux règles pratiques : @use doit se placer au début du fichier, avant les règles de style, et il ne peut pas être imbriqué dans un sélecteur.
Après @use 'abstracts/tokens', le préfixe par défaut est le dernier segment de l’URL : tokens. Vous pouvez le raccourcir avec as :
@use '../abstracts' as a;
.alerte {
color: a.$couleur-texte;
}
L’option as * supprime le préfixe, mais elle réintroduit l’ambiguïté de noms que le système de modules cherche à éviter : réservez-la à un module de confiance, utilisé partout, et plutôt rarement.
@forward : fabriquer une API interne@forward charge un module et rend ses membres publics à ceux qui chargeront votre fichier avec @use. C’est ce qui permet de regrouper plusieurs partials derrière un seul point d’accès :
// abstracts/_index.scss
@forward 'tokens';
@forward 'mixins';
Un composant n’écrit plus qu’une ligne, @use '../abstracts' as a;, et accède à a.$espace-m comme à a.a-partir-de(...). @forward accepte aussi show et hide pour limiter ce qui est exposé, et as préfixe-* pour ajouter un préfixe. Le détail est dans la documentation de @forward.
Si une valeur doit pouvoir être surchargée à l’usage (la couleur principale d’une marque, par exemple), déclarez-la avec !default puis configurez-la avec with :
// abstracts/_tokens.scss
$couleur-primaire: #0b5fff !default;
// main.scss
@use 'abstracts/tokens' with ($couleur-primaire: #c2410c);
Attention : la configuration s’applique au premier chargement du module. Faites-la dans un point d’entrée, pas au milieu d’un composant.
Si votre projet repose sur @import, l’équipe Sass fournit un outil de migration automatique, Sass Migrator, qui convertit l’essentiel du code vers @use. Lancez-le sur vos points d’entrée, relisez le résultat, puis traitez à la main les cas particuliers, comme les imports imbriqués dans un sélecteur.
abstracts/ : aucun sélecteur qui peint l’interfaceDans abstracts/, vous ne placez que des variables, des maps, des mixins et des fonctions. Aucun sélecteur de classe, aucun élément HTML. Sinon, charger un fichier « juste pour une variable » ajoute du CSS sans que personne l’ait voulu.
// abstracts/_tokens.scss
$espace-s: 0.5rem;
$espace-m: 1rem;
$rayon-s: 0.25rem;
$fond-carte: #ffffff;
$breakpoints: (
'moyen': 48rem,
'large': 64rem,
);
// abstracts/_mixins.scss
@use 'sass:map';
@use 'tokens';
@mixin a-partir-de($nom) {
@media (min-width: map.get(tokens.$breakpoints, $nom)) {
@content;
}
}
base/ : le socle génériqueRéinitialisation, typographie de base, styles des éléments HTML (body, a, h1…). Vous pouvez aussi y exposer vos jetons de design sous forme de propriétés CSS personnalisées (:root { --fond-page: … }) lorsque la valeur doit changer à l’exécution, par exemple pour un thème.
layout/ : les grandes zonesEn-tête, pied de page, grille, conteneurs de page. Un fichier de layout compose des composants, il ne les redéfinit pas.
components/ : un fichier, une responsabilité_boutons.scss décrit .bouton et ses variantes (.bouton--principal). Il ne contient pas l’en-tête entier « parce que l’en-tête a un bouton » : l’en-tête utilise la classe du bouton.
// components/_cartes.scss
@use '../abstracts' as a;
.carte {
padding: a.$espace-m;
border-radius: a.$rayon-s;
background: a.$fond-carte;
&__titre {
margin-bottom: a.$espace-s;
}
&--horizontale {
@include a.a-partir-de('moyen') {
display: flex;
gap: a.$espace-m;
}
}
}
Notez l’imbrication modérée : elle reste lisible et garde des sélecteurs de faible spécificité.
pages/ : la soupape contrôlée_accueil.scss accueille ce qui est réellement unique à la page d’accueil. Si le même bloc réapparaît ailleurs, remontez-le dans components/. Un dossier pages/ qui grossit sans frein indique une architecture qui fuit.
themes/ et vendors/themes/ contient les variantes : par exemple un mode sombre, qui redéfinit des propriétés personnalisées sous [data-theme='dark'] ou dans une requête prefers-color-scheme, plutôt que de dupliquer chaque composant. vendors/ isole le CSS de bibliothèques tierces, pour savoir à tout moment ce qui est de vous et ce qui ne l’est pas.
Une classe utilitaire (.u-sr-only, .u-mt-0) évite d’ouvrir un composant pour un détail. Limitez leur nombre et documentez-les : une jungle de classes d’espacement non commentée redevient du bruit.
Imaginons une petite équipe qui démarre un site vitrine accompagné d’un blog. Voici une marche à suivre réaliste :
abstracts/_tokens.scss (couleurs, rayons, espacements, points de rupture) et abstracts/_index.scss qui le renvoie avec @forward.base/_root.scss les propriétés personnalisées dont le thème a besoin à l’exécution.components/_boutons.scss et components/_cartes.scss, avec une imbrication limitée.layout/_header.scss, qui assemble ces composants sans les redéfinir.main.scss sans style : il ne fait qu’enchaîner les @use.L’effet recherché : une personne qui arrive sur le projet trouve où modifier l’état de survol d’un bouton sans toucher au pied de page. Si vous voulez apprendre cette discipline dans un parcours progressif qui relie CSS, SCSS et méthode, Academy Yunt propose des contenus dans cet esprit. Et si votre feuille de style actuelle est devenue un monolithe que plus personne n’ose toucher, l’audit Yunt aide à repérer les zones de risque avant de découper.
app.scss géant. Il compile, mais il ne se maintient plus : chaque modification crée un risque de conflit. Découpez avant que la peur de toucher au fichier s’installe..bouton dès qu’on charge le fichier de variables crée des surprises. Séparez la définition (dans abstracts/) de l’usage (dans components/).main.scss.@use 'tokens', appeler $bleu sans préfixe échoue : écrivez tokens.$bleu, choisissez un alias avec as, ou réservez as * aux cas justifiés.@import et @use sans plan. Les deux systèmes cohabitent pendant une migration, mais avec des comportements différents. Décidez d’une trajectoire et tenez-la.pages/ rempli de rustines est une dette : prévoyez un passage de nettoyage à chaque jalon du projet.Nommez et rangez de façon prévisible. Préfixez les partials par _ (_header.scss) pour indiquer qu’ils ne se compilent pas seuls. Le seul fichier racine est main.scss.
Gardez une seule source de vérité pour les valeurs. Pas de couleur écrite en dur dans un composant : si une valeur apparaît deux fois, c’est un jeton. Nommez les jetons selon la charte graphique ($couleur-primaire), pas selon une teinte ou une personne ($bleu-de-marc), pour réduire la traduction mentale entre la maquette et le code.
Documentez l’architecture en une page. Un styles/README.md suffit : arborescence, ordre des @use, où ajouter un composant, ce qu’il ne faut pas faire. Il est rentabilisé dès la deuxième personne qui contribue.
Outillez la structure. Un linter de styles (Stylelint, par exemple) et une compilation exécutée en intégration continue servent de filet : une architecture sans garde-fou finit toujours par se dégrader.
Faites évoluer la structure sans tout casser. Observez où apparaissent les conflits de fusion et les questions « où je mets ça ? », puis extrayez un partial quand un fichier devient pénible à relire. Si vous héritez d’un monolithe, découpez par douleur (l’en-tête qui casse à chaque campagne, le formulaire de paiement) plutôt que par ordre alphabétique, et vérifiez le rendu sur mobile et sur ordinateur avant et après chaque extraction.
Alignez le code sur le design. Quand la maquette parle de Card, le code ne devrait pas parler de .box ni d’.encart. Le même vocabulaire des deux côtés réduit les frictions.
Pensez aussi à l’accessibilité. Une arborescence claire facilite la gestion des états (focus visible, contraste, mouvement réduit), car on sait où les brancher. Pour mesurer la conformité d’un site existant, consultez les pages accessibilité et RGAA 5 de l’audit Yunt.
Ajoutez de l’abstraction après la répétition, pas avant. Quelques mixins utiles valent mieux qu’un mini-framework interne illisible.
Pour aller plus loin, vous pouvez explorer des méthodes qui vont dans le même sens (ITCSS, CUBE CSS) ou des approches centrées sur les utilitaires : les principes de couches, d’ordre et de responsabilité restent valables. Pour installer une base de styles durable sur un produit, l’agence Yunt peut vous accompagner ; vous pouvez la contacter directement. Retrouvez enfin d’autres guides sur le blog d’Academy Yunt.
Organiser ses fichiers SCSS, c’est rendre la cascade lisible pour les humains : des valeurs rangées dans abstracts/, des composants qui ont chacun une responsabilité, des pages traitées comme des exceptions, des utilitaires peu nombreux, et un main.scss qui assemble le tout dans l’ordre voulu. Le modèle 7-1 est un bon point de départ ; @use et @forward en sont le socle technique, là où @import est désormais déprécié.
Commencez petit : un dossier abstracts/, un dossier components/, un main.scss. Déplacez un seul composant, compilez, ouvrez une demande de fusion de « fondation », puis itérez.
Non. C’est un gabarit pédagogique. Adaptez-le au volume de votre projet : l’esprit (séparer valeurs, générique, composants et exceptions) compte plus que le nombre exact de dossiers.
@import ?Il fonctionne encore, mais la documentation officielle de Sass le signale comme déprécié depuis Dart Sass 1.80.0, avec un retrait prévu dans Dart Sass 3.0.0. Pour tout nouveau code, utilisez @use et @forward, et planifiez la migration des projets existants.
@use et @forward ?@use charge un module pour l’utiliser dans le fichier courant, avec un espace de noms. @forward charge un module pour rendre ses membres disponibles à ceux qui chargeront votre fichier : c’est l’outil des fichiers _index.scss.
Dans une équipe, oui : c’est ce qui évite les conflits et facilite la relecture. Seul sur un petit site, regrouper quelques micro-composants proches peut suffire, tant que le fichier reste confortable à relire.
En général près du composant concerné, avec éventuellement un mixin de point de rupture défini dans abstracts/. Évitez un unique fichier _responsive.scss qui répète tous les sélecteurs de l’application.