BaliseTonSite

Mixins & @include

Blocs réutilisables avec ou sans paramètres.

Imagine : dans ton RPG, tu as créé la recette parfaite pour forger une épée : étapes précises, matériaux, techniques... Au lieu de tout refaire à chaque fois, tu notes la recette dans ton grimoire. Maintenant, tu peux forger autant d'épées que tu veux juste en suivant ta recette ! Les mixins SCSS, c'est exactement ça : des recettes de styles que tu écris une fois et que tu réutilises partout.

5.1Créer ton premier mixin

Un mixin, c'est un bloc de CSS réutilisable que tu définis avec @mixin. Ensuite, tu l'utilises avec @include :

// Définition du mixin
@mixin bouton-base {
  padding: 0.8rem 1.5rem;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-weight: 600;
  transition: all 0.3s ease;
}

// Utilisation du mixin
.bouton-primaire {
  @include bouton-base;
  background: #3498db;
  color: white;
}

.bouton-danger {
  @include bouton-base;
  background: #e74c3c;
  color: white;
}

Le CSS généré contiendra tous les styles du mixin dans chaque sélecteur :

.bouton-primaire {
  padding: 0.8rem 1.5rem;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-weight: 600;
  transition: all 0.3s ease;
  background: #3498db;
  color: white;
}

.bouton-danger {
  padding: 0.8rem 1.5rem;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-weight: 600;
  transition: all 0.3s ease;
  background: #e74c3c;
  color: white;
}

5.2Mixins avec paramètres

Le vrai pouvoir des mixins, c'est qu'ils peuvent accepter des paramètres. Comme adapter ta recette selon les ingrédients disponibles :

// Mixin avec paramètres
@mixin bouton($couleur-fond, $couleur-texte: white) {
  padding: 0.8rem 1.5rem;
  border: none;
  border-radius: 6px;
  background: $couleur-fond;
  color: $couleur-texte;
  cursor: pointer;
  
  &:hover {
    background: darken($couleur-fond, 10%);
  }
}

// Utilisation avec paramètres
.bouton-success {
  @include bouton(#27ae60);  // couleur-texte prendra la valeur par défaut (white)
}

.bouton-warning {
  @include bouton(#f39c12, #333);  // couleur de fond ET de texte personnalisées
}

Paramètres par défaut

Tu peux définir des valeurs par défaut avec $parametre: valeur. Si l'utilisateur ne fournit pas le paramètre, la valeur par défaut sera utilisée.

5.3Mixins complexes : les techniques avancées

Les mixins peuvent contenir des règles CSS complexes, des boucles, des conditions... Voici un exemple pour créer des ombres élégantes :

@mixin ombre-elegante($niveau: 1, $couleur: rgba(0,0,0,0.1)) {
  @if $niveau == 1 {
    box-shadow: 0 2px 4px $couleur;
  } @else if $niveau == 2 {
    box-shadow: 0 4px 12px $couleur;
  } @else if $niveau == 3 {
    box-shadow: 0 8px 24px $couleur;
  } @else {
    box-shadow: 0 16px 48px $couleur;
  }
}

.carte-simple {
  @include ombre-elegante(1);
}

.carte-flottante {
  @include ombre-elegante(3, rgba(0,0,0,0.15));
}

5.4Mixin pour le responsive design

Un des cas d'usage les plus pratiques : créer des mixins pour gérer les media queries de façon élégante :

// Définition des breakpoints
$breakpoints: (
  mobile: 480px,
  tablet: 768px,
  desktop: 1024px
);

@mixin responsive($breakpoint) {
  @if map-has-key($breakpoints, $breakpoint) {
    @media (max-width: map-get($breakpoints, $breakpoint)) {
      @content;
    }
  } @else {
    @warn "Breakpoint '#{$breakpoint}' non défini.";
  }
}

// Utilisation
.hero-section {
  font-size: 3rem;
  
  @include responsive(tablet) {
    font-size: 2rem;
  }
  
  @include responsive(mobile) {
    font-size: 1.5rem;
  }
}

5.5Le mot-clé @content

Dans l'exemple précédent, tu as vu @content. C'est un placeholder qui permet d'injecter du CSS personnalisé dans ton mixin :

@mixin carte-avec-hover {
  background: white;
  border-radius: 8px;
  padding: 1rem;
  transition: transform 0.3s ease;
  
  &:hover {
    transform: translateY(-5px);
    @content;  // Le contenu personnalisé sera injecté ici
  }
}

.carte-produit {
  @include carte-avec-hover {
    // Ce contenu sera placé dans le &:hover du mixin
    box-shadow: 0 8px 24px rgba(0,0,0,0.15);
    border-color: #3498db;
  }
}

5.6Mixin vs fonctions : quelle différence ?

C'est une question fréquente. Voici la distinction :

  • Mixin : génère du CSS complet (propriétés, sélecteurs, règles)
  • Fonction : retourne une valeur unique (couleur, taille, calcul)
// ✅ Mixin : génère plusieurs propriétés CSS
@mixin centre-absolu {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

// ✅ Fonction : retourne une valeur calculée
@function em($pixels, $base: 16px) {
  @return $pixels / $base * 1em;
}

.modal {
  @include centre-absolu;  // Génère 4 propriétés CSS
  width: em(400px);        // Retourne 25em
}

5.7Organiser tes mixins

Comme pour les variables, range tes mixins dans des fichiers dédiés selon leur fonction :

abstracts/
├── _mixins-layout.scss     // Positionnement, grilles
├── _mixins-responsive.scss // Media queries
├── _mixins-animations.scss // Transitions, keyframes
└── _mixins-utilities.scss  // Ombres, boutons, utilitaires

Conseil de performance

Attention à ne pas abuser des mixins pour des styles très simples. Un mixin qui ne fait que color: red; n'a pas beaucoup d'intérêt. Réserve-les pour des blocs de styles plus complexes ou répétitifs.

5.8Mixins utiles à connaître

Voici quelques mixins classiques que tu retrouveras souvent dans les projets :

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

// Texte tronqué avec ellipse
@mixin text-ellipsis {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

// Masquer visuellement (accessibilité)
@mixin sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

Verifie tes acquis

3 questions pour valider ce chapitre

1. Quelle est la difference entre un mixin et une fonction en SCSS ?

@mixin injecte des blocs de CSS. @function calcule et retourne une valeur. On "@include" un mixin, on appelle une fonction dans une propriete.