Qu’est-ce que Sass ?
Sass signifie Syntactically Awesome Style Sheets. C’est un préprocesseur CSS — un langage qui étend le CSS classique avec des fonctionnalités de programmation et qui est compilé en CSS standard compréhensible par les navigateurs. Si vous vous êtes déjà retrouvé à répéter des valeurs de couleur, à dupliquer des media queries ou à naviguer dans des centaines de lignes de CSS plat, Sass est l’outil conçu pour résoudre ces problèmes.
Créé par Hampton Catlin en 2006, Sass a été le premier préprocesseur CSS à être largement adopté. Il a introduit des concepts issus des langages de programmation généralistes — variables, imbrication, fonctions, boucles et modules — dans l’univers des feuilles de style. Aujourd’hui, il constitue le socle de projets comme Bootstrap, Foundation et d’innombrables design systems.
La meilleure façon de concevoir Sass est de le voir comme du CSS doté d’une boîte à outils. Vous écrivez des fichiers .scss ou .sass en utilisant les fonctionnalités de Sass, vous les passez dans un compilateur, et vous obtenez des fichiers .css classiques que le navigateur peut charger. Il n’y a aucun coût au runtime. Toute la puissance réside entièrement dans votre workflow de développement.
Sass vs CSS : qu’est-ce qui change ?
Le CSS pur est un langage déclaratif — vous décrivez l’apparence des éléments, mais vous ne pouvez pas créer d’abstractions, réutiliser de la logique ou organiser votre code au-delà de la simple séparation en plusieurs fichiers. Sass répond à chacune de ces limitations :
| Capacité | CSS pur | Sass |
|---|---|---|
| Variables | Propriétés personnalisées (--var) |
$variable avec une gestion complète de la portée |
| Imbrication | Basique (désormais disponible en CSS) | Mature, avec des sélecteurs parents (&) |
| Réutilisation | Copier-coller ou classes utilitaires | Mixins, fonctions et extends |
| Organisation | @import uniquement |
@use, @forward, partials |
| Logique | Aucune | @if, @each, @for, @while |
| Calculs | calc() uniquement |
Arithmétique complète sur toutes les valeurs |
| Couleurs | Valeurs fixes | lighten, darken, mix et plus encore |
Syntaxe Sass vs SCSS
Sass supporte deux syntaxes :
SCSS (.scss) — la plus courante. Elle utilise des accolades et des points-virgules, tout comme le CSS. Tout fichier CSS valide est automatiquement un fichier SCSS valide. Cela rend l’adoption très simple :
/* style.scss */
$primary: #3498db;
.button {
background: $primary;
color: white;
&:hover {
background: darken($primary, 10%);
}
}
La syntaxe indentée (.sass) — l’originale. Elle utilise l’indentation et les retours à la ligne au lieu des accolades et des points-virgules, ce qui la rend plus concise mais moins familière :
/* style.sass */
$primary: #3498db
.button
background: $primary
color: white
&:hover
background: darken($primary, 10%)
SCSS est la syntaxe que vous rencontrerez dans pratiquement tous les projets modernes. À moins d’avoir une raison spécifique de choisir le Sass indenté, utilisez .scss.
Pourquoi Sass existe
Sass est devenu le standard de l’industrie car il répond à des problèmes concrets. Voici les principaux enjeux qu’il traite :
La répétition. Sans variables, modifier une seule couleur implique un « Rechercher et Remplacer » dans tous vos fichiers. Les variables Sass vous permettent de modifier une valeur une seule fois pour qu’elle soit mise à jour partout.
La structure plate. Des composants profondément imbriqués produisent des sélecteurs longs et répétitifs comme .card .card-header .card-title. L’imbrication (nesting) de Sass reflète la hiérarchie HTML directement dans vos styles.
L’absence de réutilisation. Le CSS ne possède pas de concept de bloc de styles réutilisable. Un composant bouton avec 10 variantes signifie 10 blocs presque identiques. Les mixins et les extends de Sass éliminent cette duplication.
L’absence de logique. Générer une palette de couleurs, alterner la couleur des lignes ou créer des breakpoints responsives à partir d’une liste nécessite des outils externes. Sass vous offre des boucles et des conditionnels directement dans votre feuille de style.
L’organisation. Importer des dizaines de fichiers CSS avec @import crée un espace de noms global plat où les collisions de noms sont inévitables. Les modules Sass (@use, @forward) règlent ce problème grâce au namespacing.
Variables
Les variables sont la fonctionnalité Sass la plus simple et la plus efficace. Une variable stocke une valeur que vous pouvez réutiliser dans l’ensemble de votre feuille de style :
/* style.scss */
$primary: #3498db;
$secondary: #2ecc71;
$font-stack: 'Helvetica Neue', Arial, sans-serif;
$spacing-unit: 8px;
body {
font-family: $font-stack;
}
.container {
padding: $spacing-unit * 3;
}
.btn-primary {
background: $primary;
color: white;
}
Modifiez $primary une seule fois en haut de votre fichier et chaque élément qui y fait référence sera mis à jour automatiquement. Les variables Sass sont des constantes définies lors de la compilation — elles n’existent pas dans le CSS final. C’est différent des propriétés personnalisées CSS (--var), qui existent dans le navigateur au moment de l’exécution. Utilisez les variables Sass pour les valeurs qui n’ont pas besoin de changer dynamiquement.
Les variables ont une portée (scope). Une variable déclarée à l’intérieur d’une règle ou d’un mixin est locale à ce bloc. Utilisez !global pour écraser une variable globale depuis une portée locale, bien que cela soit rarement nécessaire :
/* style.scss */
$color: red; // global
.box {
$color: blue; // local — only exists inside .box
color: $color;
}
// $color is still red here
L’imbrication (Nesting)
L’imbrication vous permet d’écrire des sélecteurs enfants à l’intérieur de leur parent, reflétant ainsi la structure HTML et permettant de regrouper les styles liés :
/* style.scss */
.nav {
display: flex;
gap: $spacing-unit * 2;
&__item {
padding: $spacing-unit;
&--active {
font-weight: bold;
border-bottom: 2px solid $primary;
}
&:hover {
background: rgba($primary, 0.1);
}
}
&__logo {
margin-right: auto;
}
}
Ceci est compilé en :
/* compiled.css */
.nav { display: flex; gap: 16px; }
.nav__item { padding: 8px; }
.nav__item--active { font-weight: bold; border-bottom: 2px solid #3498db; }
.nav__item:hover { background: rgba(52, 152, 219, 0.1); }
.nav__logo { margin-right: auto; }
Le sélecteur parent & est essentiel. Il fait référence au sélecteur parent, ainsi &__item à l’intérieur de .nav devient .nav__item. Sans &, Sass traite l’esperluette comme le contexte parent. Vous pouvez également utiliser & pour les pseudo-classes et les pseudo-éléments au lieu de les imbriquer dans des blocs séparés.
Bien que le CSS natif supporte désormais l’imbrication basique, l’imbrication de Sass est plus mature — elle supporte & pour des références parentales arbitraires, fonctionne partout et a été éprouvée depuis plus d’une décennie.
Partials et imports
Les partials sont des fichiers Sass destinés à être importés et non à être compilés seuls. Nommez-les avec un préfixe underscore — _variables.scss, _buttons.scss, _mixins.scss — et Sass les ignorera lors de la compilation directe :
// _variables.scss
$primary: #3498db;
$spacing: 8px;
$font-stack: 'Helvetica Neue', Arial, sans-serif;
// _buttons.scss
@use 'variables' as *;
.button {
padding: $spacing * 2;
background: $primary;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
// main.scss
@use 'variables' as *;
@use 'buttons';
@use 'layout';
@use 'typography';
La règle @use importe un fichier en tant que module. Vous accédez ensuite à ses membres via un espace de noms (namespace), ou utilisez as * pour tout importer dans la portée actuelle. Cela permet de garder votre espace de noms global propre et d’éviter les collisions de nommage entre les fichiers.
Modules : @use et @forward
La règle @import est obsolète. Elle fusionnait tous les fichiers dans une portée globale unique, ce qui signifie qu’un $primary dans un fichier pouvait écraser silencieusement un $primary dans un autre. Les alternatives modernes sont @use et @forward.
@use
@use importe un module et lui attribue un espace de noms (namespace) :
/* style.scss */
@use 'variables';
.button {
background: variables.$primary;
padding: variables.$spacing * 2;
}
Vous pouvez créer un alias pour l’espace de noms ou importer tous les membres dans la portée actuelle :
/* style.scss */
@use 'variables' as v;
@use 'variables' as *; // no namespace needed
@forward
@forward ré-exporte les membres d’un module afin que les fichiers important le module actuel puissent y accéder. On l’utilise pour créer des “barrel files” — un point d’entrée unique qui expose plusieurs modules :
// _index.scss
@forward 'variables';
@forward 'mixins';
@forward 'functions';
// main.scss
@use 'index' as *; // gets everything from variables, mixins and functions
Utilisez @forward avec show et hide pour contrôler quels membres sont ré-exportés :
/* style.scss */
@forward 'variables' show $primary, $secondary;
@forward 'mixins' hide $internal-helper;
Mixins
Les mixins sont des blocs de styles réutilisables que vous pouvez paramétrer et inclure n’importe où. Considérez-les comme des fonctions qui génèrent des déclarations CSS :
/* mixins.scss */
@mixin flex-center {
display: flex;
justify-content: center;
align-items: center;
}
@mixin respond-to($breakpoint) {
@if $breakpoint == 'tablet' {
@media (min-width: 768px) { @content; }
} @else if $breakpoint == 'desktop' {
@media (min-width: 1024px) { @content; }
}
}
.hero {
@include flex-center;
min-height: 100vh;
@include respond-to('desktop') {
min-height: 80vh;
}
}
.card {
@include flex-center;
padding: 1rem;
}
Les mixins peuvent avoir des paramètres par défaut, accepter un nombre variable d’arguments et utiliser @content pour accepter un bloc de styles provenant de l’appelant. Ils constituent le principal mécanisme d’abstraction dans Sass — les design systems, les helpers responsives et les couches de compatibilité cross-browser sont tous basés sur les mixins.
Fonctions
Les fonctions Sass calculent et retournent une valeur. Elles sont similaires aux mixins, mais au lieu de générer du CSS, elles produisent une valeur que vous pouvez assigner :
/* functions.scss */
@function spacing($n) {
@return $n * 8px;
}
@function shade($color, $percentage) {
@return mix(black, $color, $percentage);
}
.hero {
padding: spacing(4); // 32px
background: shade(#3498db, 20%);
}
.sidebar {
padding: spacing(2); // 16px
}
Sass est livré avec de nombreuses fonctions intégrées pour les couleurs (lighten, darken, saturate, adjust-hue), les chaînes de caractères (str-length, str-insert), les mathématiques (abs, min, max, round) et les listes (length, nth, append, index). Vous pouvez écrire vos propres fonctions pour vos logiques spécifiques au projet.
Extends et héritage
La règle @extend permet à un sélecteur d’hériter des styles d’un autre. Sass fusionne les deux sélecteurs en une seule règle dans le CSS de sortie :
/* style.scss */
%message {
padding: 1rem;
border-radius: 4px;
margin-bottom: 1rem;
}
.success {
@extend %message;
background: #d4edda;
color: #155724;
}
.error {
@extend %message;
background: #f8d7da;
color: #721c24;
}
.warning {
@extend %message;
background: #fff3cd;
color: #856404;
}
Compile en :
/* compiled.css */
.success, .error, .warning {
padding: 1rem;
border-radius: 4px;
margin-bottom: 1rem;
}
.success { background: #d4edda; color: #155724; }
.error { background: #f8d7da; color: #721c24; }
.warning { background: #fff3cd; color: #856404; }
Les placeholders (sélecteurs commençant par %) ne sont pas exportés dans le CSS par eux-mêmes — ils n’apparaissent que lorsqu’ils sont étendus. Cela évite d’avoir des règles vides dans votre fichier compilé.
Utilisez @extend pour les motifs structurels partagés. Pour tout ce qui nécessite des paramètres, utilisez plutôt un mixin — @extend ne peut pas accepter d’arguments.
Opérateurs
Sass prend en charge les opérateurs arithmétiques standards pour travailler avec des nombres :
/* style.scss */
$column-count: 12;
$gutter: 24px;
$gap: $gutter / 2; // 12px
$base: 16px;
$heading-1: $base * 2; // 32px
$heading-2: $base * 1.5; // 24px
$full-width: 100%;
$sidebar: $full-width / 3; // 33.333%
// Remainder
$remainder: 17 % 5; // 2
Sass prend également en charge l’interpolation de chaînes, les opérateurs de comparaison et les opérateurs booléens :
/* style.scss */
$primary: #3498db;
$dark: darken($primary, 20%);
$is-dark: true;
@mixin theme-bg {
@if $is-dark {
background: $dark;
} @else {
background: $primary;
}
}
Gardez à l’esprit que la division (/) est désormais traitée comme une fraction CSS dans certains contextes (par exemple font: 16px/1.5). Encapsulez vos divisions dans math.div() pour éviter toute ambiguïté, ou utilisez calc() pour les divisions dynamiques.
Flux de contrôle
Sass inclut des conditionnels et des boucles qui génèrent du CSS lors de la compilation :
@if / @else
/* style.scss */
$theme: 'light';
@mixin theme-bg {
@if $theme == 'light' {
background: white;
color: black;
} @else if $theme == 'dark' {
background: #1a1a2e;
color: white;
} @else {
background: #f0f0f0;
color: #333;
}
}
@each
Permet d’itérer sur une liste ou une map :
/* style.scss */
$colors: (
primary: #3498db,
secondary: #2ecc71,
danger: #e74c3c,
);
@each $name, $color in $colors {
.text-#{$name} {
color: $color;
}
.bg-#{$name} {
background: $color;
}
}
@for
Génère une plage de sélecteurs :
/* style.scss */
@for $i from 1 through 12 {
.col-#{$i} {
width: ($i / 12) * 100%;
}
}
@for $i from 1 through 5 {
.mt-#{$i} {
margin-top: $i * 8px;
}
}
@while
Exécute une boucle tant qu’une condition est vraie :
/* style.scss */
$columns: 12;
$i: $columns;
@while $i > 0 {
.col-#{$i} {
width: ($i / $columns) * 100%;
}
$i: $i - 1;
}
Maps et listes
Sass propose des structures de données natives pour les collections.
Les listes sont ordonnées et séparées par des virgules ou des espaces :
/* style.scss */
$breakpoints: 480px, 768px, 1024px, 1280px;
@each $bp in $breakpoints {
@media (min-width: $bp) {
.container {
max-width: $bp;
}
}
}
// Lists can be nested
$margins: (8px, 16px, 24px, 32px);
Les maps sont des paires clé-valeur, similaires aux objets ou aux dictionnaires :
/* style.scss */
$theme: (
primary: #3498db,
secondary: #2ecc71,
bg: white,
text: #333,
);
@each $key, $value in $theme {
--color-#{$key}: #{$value};
}
Vous pouvez accéder aux valeurs d’une map avec map-get, les fusionner avec map-merge, vérifier l’existence d’une clé avec map-has-key et itérer avec @each.
Fonctions intégrées de Sass
Sass est livré avec une bibliothèque standard complète :
/* style.scss */
// Colour manipulation
$primary: #3498db;
.lighter { color: lighten($primary, 20%); }
.darker { color: darken($primary, 15%); }
.desaturated { color: desaturate($primary, 30%); }
.hue-shifted { color: adjust-hue($primary, 30deg); }
// Colour functions
$alpha: rgba($primary, 0.5); // semi-transparent
$contrast: contrast-color($primary); // contrast-safe colour
// Maths
$rounded: round(3.14); // 3
$limited: clamp(1, 10, 5); // 5
$half: math.div(100%, 2); // 50%
// Strings
$name: to-upper-case('sass'); // SASS
$length: str-length('hello'); // 5
$joined: str-insert('hello', ' world', 6); // 'hello world'
// Lists
$items: append(1px, 2px, 3px, 4px);
$first: nth($items, 1); // 1px
$count: length($items); // 4
Ces fonctions sont disponibles globalement en SCSS et via @use 'sass:color', @use 'sass:math', @use 'sass:string', @use 'sass:list' et @use 'sass:map'.
Comment utiliser Sass
Dart Sass
Dart Sass est l’implémentation canonique et la seule activement maintenue de Sass. Installez-la avec :
npm install sass
Ensuite, compilez vos fichiers directement :
npx sass src/styles.scss dist/styles.css
Intégration aux outils de build
Dans la plupart des projets modernes, Sass est géré par votre bundler. Vite, webpack, Parcel et esbuild supportent tous Sass nativement :
Vite — installez simplement sass et importez des fichiers .scss :
import './styles.scss';
webpack — ajoutez sass-loader :
module.exports = {
module: { rules: [{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }] }
};
Compilation via CLI
# Watch mode — recompile on every save
npx sass --watch src:dist
# One compile
npx sass src/styles.scss dist/styles.css
# Output compressed CSS
npx sass --style=compressed src/styles.scss dist/styles.css
Bonnes pratiques
- Utilisez la syntaxe SCSS. Elle est compatible avec CSS, largement adoptée et bien plus lisible que la syntaxe indentée.
- Utilisez
@useet@forward, jamais@import. Le système d’import est obsolète et provoque une pollution de la portée globale. - Organisez-vous avec des partials. Une responsabilité par fichier :
_variables.scss,_mixins.scss,_buttons.scss,_layout.scss. - Namespacez vos modules. Utilisez
@use 'module' as varou laissez le namespace par défaut (module.$var) clarifier l’origine des valeurs. - Utilisez des placeholders pour les patterns partagés. Les sélecteurs
%placeholderne génèrent du CSS que lorsqu’ils sont étendus, ce qui permet de garder un rendu léger. - Privilégiez les mixins paramétrées aux extends. Les mixins sont plus flexibles et produisent un CSS explicite et prévisible.
- Gardez la logique métier hors des feuilles de style. Les fonctions et les boucles Sass ont leur place dans votre pipeline de build, pas dans la logique de vos composants.
- Lintez votre Sass. Utilisez
stylelintavec un plugin Sass pour détecter les dépréciations et imposer des conventions. - Générez du CSS compressé pour la production. Utilisez
--style=compressedou laissez votre bundler minifier le code. - Évitez les sélecteurs trop imbriqués. Deux ou trois niveaux suffisent. Une imbrication plus profonde signale généralement un problème de nommage ou de structure.