Sass & SCSS

Découvrez la puissance de Sass, le préprocesseur CSS qui révolutionne votre façon d’écrire et d’organiser vos feuilles de style.

Pourquoi Sass & SCSS

Un préprocesseur ajoute au CSS ce qu’il n’a jamais eu : des variables nommées, de l’imbrication, des blocs réutilisables et des fonctions.

CSS vanilla

css

/* CSS traditionnel */
.header { background: #cf649a; }
.header__title {
  color: white;
  font-size: 2rem;
}
.header__subtitle {
  color: rgba(255,255,255,0.8);
  font-size: 1.2rem;
}

.button {
  background: #cf649a;
  padding: 8px 16px;
  border-radius: 4px;
}
.button:hover {
  background: #b85588;
}

  • Répétition de code
  • Pas de variables natives (avant CSS3)
  • Maintenance difficile
  • Pas de réutilisabilité
  • Code non structuré

Sass (syntaxe indentée)

scss

// Sass - Syntaxe indentée
$primary: #cf649a
$primary-dark: darken($primary, 10%)

.header
  background: $primary

  &__title
    color: white
    font-size: 2rem

  &__subtitle
    color: rgba(white, 0.8)
    font-size: 1.2rem

=button-style($bg, $padding: 8px 16px)
  background: $bg
  padding: $padding
  border-radius: 4px

  &:hover
    background: darken($bg, 10%)

.button
  +button-style($primary)

  • Variables natives
  • Nesting (imbrication)
  • Mixins réutilisables
  • Fonctions intégrées
  • Syntaxe concise

SCSS (Sassy CSS)

scss

// SCSS - Syntaxe CSS étendue
$primary: #cf649a;
$primary-dark: darken($primary, 10%);

.header {
  background: $primary;

  &__title {
    color: white;
    font-size: 2rem;
  }

  &__subtitle {
    color: rgba(white, 0.8);
    font-size: 1.2rem;
  }
}

@mixin button-style($bg, $padding: 8px 16px) {
  background: $bg;
  padding: $padding;
  border-radius: 4px;

  &:hover {
    background: darken($bg, 10%);
  }
}

.button {
  @include button-style($primary);
}

  • Compatible CSS existant
  • Plus populaire que Sass
  • Syntaxe familière
  • Transition facile depuis CSS
  • Toutes les fonctionnalités Sass

Processus de compilation

SCSS source

scss

$primary: #cf649a;

.card {
  background: $primary;
  padding: 1rem;

  &:hover {
    background: darken($primary, 10%);
  }
}

CSS compilé

css

.card {
  background: #cf649a;
  padding: 1rem;
}

.card:hover {
  background: #b85588;
}

Le navigateur ne voit que du CSS classique.

Syntaxes : Sass ou SCSS

Deux écritures pour le même langage. L’une supprime accolades et points-virgules, l’autre reste du CSS valide.

Comparaison des syntaxes

Sass (syntaxe indentée)

scss

// Variables
$primary-color: #cf649a
$font-size-large: 1.5rem
$border-radius: 8px

// Nesting
.card
  background: white
  padding: 1rem
  border-radius: $border-radius

  .title
    color: $primary-color
    font-size: $font-size-large
    margin-bottom: 0.5rem

  .content
    color: #666
    line-height: 1.6

  &:hover
    transform: translateY(-2px)
    box-shadow: 0 4px 15px rgba(0,0,0,0.1)

SCSS (syntaxe CSS étendue)

scss

// Variables
$primary-color: #cf649a;
$font-size-large: 1.5rem;
$border-radius: 8px;

// Nesting
.card {
  background: white;
  padding: 1rem;
  border-radius: $border-radius;

  .title {
    color: $primary-color;
    font-size: $font-size-large;
    margin-bottom: 0.5rem;
  }

  .content {
    color: #666;
    line-height: 1.6;
  }

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 15px rgba(0,0,0,0.1);
  }
}

Sass — avantages et inconvénients

Avantages

  • Code plus concis (pas de {} ni ;)
  • Indentation naturelle
  • Moins de caractères à taper
  • Syntaxe « Python-like »

Inconvénients

  • Sensible à l’indentation
  • Transition plus difficile depuis CSS
  • Moins populaire
  • Courbe d’apprentissage

SCSS — avantages et inconvénients

Avantages

  • Compatible 100 % avec CSS existant
  • Plus populaire et documenté
  • Transition facile depuis CSS
  • Syntaxe familière

Inconvénients

  • Plus verbeux que Sass
  • Accolades et points-virgules requis
  • Fichiers légèrement plus longs

Recommandation

SCSS est généralement recommandé pour les débutants car il est plus facile à adopter depuis du CSS existant. Sass est excellent si vous préférez une syntaxe plus concise et n’avez pas peur du changement.

Fonctionnalités principales

Quatre apports qui font tout : variables, imbrication, mixins, fonctions.

Variables

scss

// Types de variables Sass/SCSS
$primary-color: #cf649a;       // Couleur
$font-size: 16px;              // Taille
$font-family: 'Arial', sans-serif; // Police
$border-width: 2px;            // Nombre
$is-rounded: true;             // Booléen
$margin-sizes: 10px 15px 20px; // Liste
$font-weights: (
  light: 300,
  normal: 400,
  bold: 700
);                             // Map

// Utilisation
.button {
  color: $primary-color;
  font-size: $font-size;
  font-family: $font-family;
  border: $border-width solid $primary-color;
  border-radius: if($is-rounded, 8px, 0);
  font-weight: map-get($font-weights, bold);
}

--sass-primary

Variables Sass !

--sass-primary: ;

En Sass la variable est résolue à la compilation ; ici c’est une custom property, pour que le changement soit visible sans recompiler.

Nesting (imbrication)

scss

// SCSS avec nesting
.navbar {
  background: $primary-color;
  padding: 1rem;

  // Élément enfant
  .logo {
    font-size: 1.5rem;
    font-weight: bold;
    color: white;
  }

  // Liste de navigation
  .nav-list {
    list-style: none;
    display: flex;
    gap: 1rem;

    .nav-item {
      padding: 0.5rem 1rem;

      a {
        color: white;
        text-decoration: none;

        &:hover {
          color: lighten($primary-color, 20%);
        }
      }
    }
  }

  // Pseudo-sélecteurs avec &
  &:hover {
    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  }

  // Modificateurs avec &
  &--dark {
    background: darken($primary-color, 20%);
  }
}

Un seul bloc .navbar en SCSS produit toutes les règles descendantes.

Attention

Évitez l’imbrication trop profonde — trois niveaux au maximum. Au-delà, le CSS produit devient très spécifique et difficile à maintenir.

Mixins

scss

// Définition de mixins
@mixin button-style($bg: $primary-color, $padding: 12px 24px) {
  background: $bg;
  color: white;
  padding: $padding;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  font-weight: 600;
  transition: all 0.3s ease;

  &:hover {
    background: darken($bg, 10%);
    transform: translateY(-2px);
    box-shadow: 0 8px 25px rgba($bg, 0.3);
  }

  &:active {
    transform: translateY(0);
  }
}

@mixin flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

@mixin media-query($breakpoint) {
  @if $breakpoint == mobile {
    @media (max-width: 767px) { @content; }
  }
  @if $breakpoint == tablet {
    @media (min-width: 768px) and (max-width: 1023px) { @content; }
  }
  @if $breakpoint == desktop {
    @media (min-width: 1024px) { @content; }
  }
}

// Utilisation des mixins
.btn-primary {
  @include button-style($primary-color, 16px 32px);
}

.btn-secondary {
  @include button-style($secondary-color);
}

.hero-section {
  @include flex-center;
  height: 100vh;

  @include media-query(mobile) {
    height: 50vh;
    flex-direction: column;
  }
}

Un seul bloc de code, trois tailles — le paramètre fait la différence.

Avantages des mixins

  • Réutilisation de blocs de code
  • Paramètres avec valeurs par défaut
  • Logique conditionnelle avec @if
  • Contenu dynamique avec @content

Fonctions

scss

// Fonctions Sass intégrées
$primary: #cf649a;

.element {
  // Manipulation de couleurs
  background: $primary;
  border: 1px solid darken($primary, 15%);
  color: lighten($primary, 40%);

  &:hover {
    background: saturate($primary, 20%);
  }

  &:active {
    background: desaturate($primary, 10%);
  }
}

// Fonctions personnalisées
@function rem($pixels) {
  @return #{$pixels / 16}rem;
}

@function color-contrast($color) {
  @if (lightness($color) > 50%) {
    @return #000;
  } @else {
    @return #fff;
  }
}

@function strip-unit($number) {
  @if type-of($number) == 'number' and not unitless($number) {
    @return $number / ($number * 0 + 1);
  }
  @return $number;
}

// Utilisation des fonctions personnalisées
.card {
  font-size: rem(18);
  padding: rem(16) rem(24);
  background: $primary;
  color: color-contrast($primary);
}

// Fonctions de liste et map
$breakpoints: (
  small: 480px,
  medium: 768px,
  large: 1024px
);

@function breakpoint($size) {
  @return map-get($breakpoints, $size);
}

.responsive-container {
  width: 100%;

  @media (min-width: breakpoint(medium)) {
    max-width: 1200px;
  }
}

Fonctions utilitaires

scss

// Exemples d'utilisation
font-size: rem(18); // 1.125rem
color: color-contrast(#cf649a); // #fff
width: strip-unit(100px); // 100
breakpoint: breakpoint(medium); // 768px

darken, lighten et saturate produisent ces trois teintes à partir de #cf649a.

Types de fonctions

  • Couleurs : darken(), lighten(), saturate()…
  • Nombres : round(), ceil(), floor()…
  • Strings : quote(), unquote()…
  • Listes : length(), nth(), append()…
  • Maps : map-get(), map-keys()…

@use et @forward — le système de modules

@import recopiait un fichier dans un autre. Tout s’y mélangeait : deux fichiers déclarant $primary se marchaient dessus, et rien ne disait d’où venait une variable. @use charge un fichier une seule fois et lui donne un espace de nom. On sait enfin qui a écrit quoi.

⚠️ @import est en fin de vie

Les exemples de cette page emploient @import, la syntaxe historique de Sass. Elle est dépréciée depuis Dart Sass 1.80, parue en octobre 2024, et sera supprimée dans Dart Sass 3.0, annoncée pour octobre 2026 au plus tôt. Concrètement : si vous installez Sass aujourd’hui, @import fonctionne encore mais affiche un avertissement à chaque compilation ; à la sortie de la 3.0, il cessera de fonctionner.

  • Écrivez vos nouveaux projets avec @use et @forward.
  • Les exemples en @import restent ici parce que vous les rencontrerez encore longtemps dans du code existant : savoir les lire fait partie du métier.
  • Source : sass-lang.com/blog/import-is-deprecated, consulté en août 2026.

Trois différences à connaître

  • Un fichier chargé deux fois par @use n’est compilé qu’UNE fois — @import le recopiait à chaque appel.
  • Les membres d’un module sont PRÉFIXÉS par son nom : variables.$primary, pas $primary.
  • Les variables ne sont PLUS globales : chaque fichier qui a besoin de $primary doit le charger lui-même. C’est le changement qui surprend le plus.

La syntaxe

scss

// Charger un module, préfixe = nom du fichier
@use 'abstracts/variables';
.bouton { color: variables.$primary; }

// Choisir son préfixe
@use 'abstracts/variables' as v;
.bouton { color: v.$primary; }

// Sans préfixe — pratique, mais on perd la traçabilité
@use 'abstracts/variables' as *;
.bouton { color: $primary; }

// Regrouper plusieurs modules derrière un seul point d'entrée
// abstracts/_index.scss
@forward 'variables';
@forward 'functions';
@forward 'mixins';

L’architecture 7-1 en @use

scss

// abstracts/_index.scss — le point d'entrée des outils
@forward 'variables';
@forward 'functions';
@forward 'mixins';
@forward 'placeholders';

// components/_buttons.scss — chaque partiel charge ce dont IL a besoin
@use '../abstracts' as *;

.bouton {
  background: $primary;
  @include bouton-base;
}

// main.scss — point d'entrée
// 1. Vendors
@use 'vendors/bootstrap';
// 2. Base
@use 'base/reset';
@use 'base/typography';
@use 'base/utilities';
// 3. Layout
@use 'layout/header';
@use 'layout/navigation';
@use 'layout/sidebar';
@use 'layout/footer';
// 4. Components
@use 'components/buttons';
@use 'components/forms';
@use 'components/cards';
// 5. Pages
@use 'pages/home';
@use 'pages/about';
// 6. Themes
@use 'themes/light';
@use 'themes/dark';

Le pendant du main.scss en @import, plus bas.

Ce qui change dans la pratique

  • abstracts/ n’apparaît plus dans main.scss : ce sont des outils, pas du CSS. Chaque partiel les charge lui-même.
  • Un _index.scss par dossier évite d’écrire quatre @use dans chaque fichier.
  • L’ordre de main.scss compte toujours pour la cascade CSS — c’est la seule chose que @use ne change pas.

Architecture & organisation

Sept dossiers, un point d’entrée. La règle tient en une phrase et se lit dans l’arborescence.

Structure de fichiers recommandée

text

scss/
├── abstracts/
│   ├── _variables.scss
│   ├── _mixins.scss
│   ├── _functions.scss
│   └── _placeholders.scss
├── base/
│   ├── _reset.scss
│   ├── _typography.scss
│   └── _utilities.scss
├── components/
│   ├── _buttons.scss
│   ├── _cards.scss
│   ├── _forms.scss
│   └── _navigation.scss
├── layout/
│   ├── _header.scss
│   ├── _footer.scss
│   ├── _sidebar.scss
│   └── _grid.scss
├── pages/
│   ├── _home.scss
│   ├── _about.scss
│   └── _contact.scss
├── themes/
│   ├── _light.scss
│   └── _dark.scss
├── vendors/
│   ├── _bootstrap.scss
│   └── _jquery-ui.scss
└── main.scss

Fichier main.scss

scss

// main.scss - Point d'entrée

// 1. Abstracts
@import 'abstracts/variables';
@import 'abstracts/functions';
@import 'abstracts/mixins';
@import 'abstracts/placeholders';

// 2. Vendors
@import 'vendors/bootstrap';

// 3. Base
@import 'base/reset';
@import 'base/typography';
@import 'base/utilities';

// 4. Layout
@import 'layout/header';
@import 'layout/navigation';
@import 'layout/sidebar';
@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/light';
@import 'themes/dark';

Écriture historique, en @import. La version @use est dans la section précédente.

Règle des 7±2

Organisez vos fichiers en maximum 7 catégories pour maintenir une architecture claire et navigable.

Méthodologies & conventions

Outils et build process

Points d’attention

  • Utilisez Dart Sass (dernière version)
  • Évitez LibSass (deprecated)
  • Source maps pour le debug
  • Compression pour la production
  • Watch mode pour le développement

Exercices pratiques

Trois exercices progressifs, du design system au micro-framework.

  1. Exercice 1 : design system avec Sass

    Créez un design system complet.

    Objectifs

    • Définir des variables pour couleurs, tailles, espacements
    • Créer des mixins pour boutons, cards, layouts
    • Utiliser le nesting pour l’organisation
    • Implémenter des fonctions utilitaires
    • Structure modulaire avec @import
    • Thèmes clair/sombre

    Structure de départ

    scss

    // _variables.scss
    $primary: #cf649a;
    $secondary: #3b82f6;
    $success: #10b981;
    
    $space-xs: 0.25rem;
    $space-sm: 0.5rem;
    $space-md: 1rem;
    
    $breakpoints: (
      mobile: 480px,
      tablet: 768px,
      desktop: 1024px
    );
    
    // _mixins.scss
    @mixin button($bg: $primary) {
      // Votre code ici
    }
    
    @mixin card($padding: $space-md) {
      // Votre code ici
    }
    
    // main.scss
    @import 'variables';
    @import 'mixins';
    @import 'components';

    Conseils

    Commencez par définir vos variables de base, puis créez des mixins réutilisables. Utilisez les fonctions Sass pour manipuler les couleurs et créer des variantes automatiquement.

  2. Exercice 2 : site responsive avec SCSS

    Site adaptatif avec architecture Sass.

    Fonctionnalités requises

    • Header responsive avec navigation
    • Grille de produits adaptative
    • Footer avec liens sociaux
    • Animations CSS3
    • Mixins pour breakpoints
    • Organisation BEM + Sass
    • Dark mode avec variables

    Mixins utiles

    scss

    // Breakpoints mixin
    @mixin respond-to($breakpoint) {
      @if $breakpoint == mobile {
        @media (max-width: 767px) {
          @content;
        }
      }
      @if $breakpoint == tablet {
        @media (min-width: 768px) {
          @content;
        }
      }
    }
    
    // Grid mixin
    @mixin grid($cols, $gap: 1rem) {
      display: grid;
      grid-template-columns: repeat($cols, 1fr);
      gap: $gap;
    
      @include respond-to(mobile) {
        grid-template-columns: 1fr;
      }
    }
    
    // Animation mixin
    @mixin animate($property: all, $duration: 0.3s) {
      transition: $property $duration ease;
    }

  3. Exercice 3 : framework CSS personnalisé

    Créez votre propre micro-framework.

    Composants à développer

    • Composants UI : boutons (variants, tailles), cards (styles, layouts), forms (inputs, validations), navigation (menu, breadcrumb)
    • Système de layout : grille flexible, conteneurs responsives, utilitaires spacing, flexbox helpers
    • Utilitaires : classes de couleurs, helpers typographie, états (show/hide), animations

    Génération automatique de classes

    scss

    // Exemple de génération automatique
    $spacings: (1: 0.25rem, 2: 0.5rem, 3: 1rem, 4: 1.5rem);
    
    @each $name, $value in $spacings {
      .p-#{$name} { padding: $value; }
      .m-#{$name} { margin: $value; }
    }
    
    // Génère: .p-1, .p-2, .m-1, .m-2, etc.

    Challenge bonus

    Créez un système de génération automatique de classes utilitaires (comme Tailwind) en utilisant les boucles Sass et les maps.

Sass & SCSS sont acquis

Vous avez maintenant toutes les clés pour transformer votre façon d’écrire du CSS. Sass améliore la productivité et la maintenabilité de vos projets.

  • 📦 Variables

    Principe DRY et réutilisabilité

  • 🎯 Nesting

    Organisation hiérarchique claire

  • 🔧 Mixins

    Blocs de code réutilisables

  • ⚙️ Functions

    Logique et calculs dynamiques

Les autres pages CSS