Mixins et variables SCSS : le guide pratique
Variables et mixins SCSS rendent vos styles réutilisables, à condition de les nommer et de les limiter. Patterns solides, erreurs fréquentes et alternatives modernes.

Variables et mixins SCSS rendent vos styles réutilisables, à condition de les nommer et de les limiter. Patterns solides, erreurs fréquentes et alternatives modernes.

Variables et mixins sont le duo que tout le monde cite quand on parle de SCSS — parfois trop vite. Mal nommées, les variables deviennent un tiroir fourre-tout. Mal conçus, les mixins génèrent du CSS bloat. Ce guide pratique montre comment les utiliser avec mesure, avec des exemples concrets, leurs limites, et les alternatives modernes (custom properties, utilitaires).
Une variable Sass ($espace-m) est résolue à la compilation. Le CSS final contient la valeur calculée, pas $espace-m. Idéal pour :
Un mixin est un bloc de styles réutilisable, éventuellement paramétré, injecté via @include. Idéal pour :
Ce n’est pas un composant UI à lui seul : le mixin n’a pas de classe magique tant que vous ne l’incluez pas dans un sélecteur.
--couleur-lien vit dans le navigateur, peut changer au runtime (thème, composant). Complémentaire, pas ennemi : beaucoup d’équipes génèrent des custom properties à partir de variables Sass.
// abstracts/_tokens.scss
$bleu-600: #1a73e8;
$gris-900: #1a1a1a;
$espace-s: 0.5rem;
$espace-m: 1rem;
$rayon-s: 0.25rem;
// Sémantique > palette brute quand c’est possible
$couleur-texte: $gris-900;
$couleur-action: $bleu-600;
Les noms sémantiques ($couleur-action) protègent quand la marque change de bleu. Gardez parfois la palette brute pour les designers qui parlent en teintes.
@mixin truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.carte__titre {
@include truncate;
max-width: 20ch;
}
Trois lignes de CSS en mixin : OK si le pattern revient souvent. Sinon, une utility .u-truncate peut suffire.
@mixin flex-centre($direction: row, $gap: $espace-s) {
display: flex;
flex-direction: $direction;
align-items: center;
justify-content: center;
gap: $gap;
}
.hero__cta {
@include flex-centre($gap: $espace-m);
}
Limitez le nombre de paramètres. Au-delà de trois ou quatre, un mixin devient une mini-API difficile à mémoriser.
$bp-md: 48rem;
$bp-lg: 64rem;
@mixin media-up($bp) {
@media (min-width: $bp) {
@content;
}
}
.grille {
display: grid;
gap: $espace-s;
@include media-up($bp-md) {
grid-template-columns: repeat(2, 1fr);
gap: $espace-m;
}
}
@content permet d’injecter le bloc appelant dans le media query. Toute l’équipe parle le même langage (bp-md) au lieu de 768px magiques éparpillés.
$espacements: (
'0': 0,
's': 0.5rem,
'm': 1rem,
'l': 2rem,
);
@each $nom, $valeur in $espacements {
.u-mt-#{$nom} {
margin-top: $valeur;
}
}
Utile pour une petite échelle d’utilities. Dangereux si vous générez des centaines de classes « au cas où » : le CSS livré enfle, le purge devient obligatoire.
Besoin : deux variants, états hover/focus/disabled, cohérents sur tout le site.
$couleur-action, $couleur-action-hover, $rayon-s, $espace-s.bouton-reset : bordure, fond, typo, curseur, transition légère.focus-visible-ring partagé avec les liens et champs..bouton--primary et .bouton--ghost qui n’incluent que ce qui change (couleurs, bordures).pointer-events centralisés, pas recopiés.@mixin focus-visible-ring {
&:focus-visible {
outline: 2px solid $couleur-action;
outline-offset: 2px;
}
}
@mixin bouton-base {
display: inline-flex;
align-items: center;
gap: $espace-s;
padding: $espace-s $espace-m;
border-radius: $rayon-s;
font: inherit;
cursor: pointer;
@include focus-visible-ring;
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
}
.bouton--primary {
@include bouton-base;
background: $couleur-action;
color: #fff;
border: none;
}
Vous gagnez la cohérence focus (accessibilité) sans la redemander à chaque composant. Pour intégrer ces gestes dans un apprentissage structuré, Academy Yunt relie CSS accessible et factorisation SCSS. Agency industrialise ce type de design system sur des produits réels. Un audit repère souvent des mixins dupliqués et des contrastes oubliés.
$bleu, $bleu2, $bleu-final-v3 : signe qu’il manque une couche sémantique et un ménage. Archivez, ne renommez pas en silence.
Vingt paramètres booléens ($large, $ombre, $icon, $rounded…) reproduisent un framework illisible. Préférez des modifiers CSS ou des mixins spécialisés.
Chaque @include copie les déclarations dans le sélecteur. Un gros mixin inclus cinquante fois = CSS répétitif. Parfois une classe partagée est plus saine qu’un mixin.
$var et var(--x) sans stratégieDécidez ce qui est build-time et ce qui est runtime. Documentez la passerelle (:root { --x: #{$var}; }).
color.scale et consorts peuvent produire des teintes hors critères d’accessibilité. Vérifiez les contrastes sur les paires texte/fond réelles.
line-clamp, aspect-ratio, nesting natif : vérifiez si le mixin apporte encore de la valeur.
$espace-m dans une échelle > $padding-carte-interne-spécial. Les exceptions se gèrent au niveau composant.
Ouvrez le fichier compilé. Cherchez les répétitions massives. Ajustez mixin vs classe partagée.
@use et namespaces@use 'tokens' as t;
.titre { color: t.$couleur-texte; }
Moins de collisions, intentions visibles à la lecture.
Deux lignes de commentaire : but, paramètres, exemple. Les mixins « internes » peuvent rester locaux au fichier.
Sass fixe la structure ; le navigateur bascule les couleurs. Meilleur des deux mondes pour clair/sombre.
Focus visible, zones tactiles, contrastes : factoriser sans dégrader l’expérience. L’écosystème Yunt rappelle que la qualité front se mesure aussi hors DevTools.
@layer pour ordonner reset / composants / utilities sans guerre de spécificité.SCSS reste excellent pour assembler et paramétrer. Il n’est plus le seul outil de factorisation.
Sur un projet de taille moyenne, une « lib » SCSS d’équipe peut tenir en une page de README :
focus-visible-ring, media-up, truncate).@forward.Cette discipline évite que chaque feature invente son propre $bleu-cta-2. En revue de code, la question devient simple : « est-ce déjà dans la lib ? sinon, mérite-t-il d’y entrer ? ». Si la réponse est non, le style reste local au composant — et c’est très bien ainsi.
Pensez aussi au versionnement mental : quand vous cassez un mixin public (changement de signature), prévenez l’équipe comme pour une API. Un @include media-up modifié silencieusement peut casser le responsive sur dix pages sans erreur de compilation.
Consultez la documentation officielle sur les mixins et les variables Sass. Pour la suite :
Build-time et calculs : Sass. Thème, override local, lecture JS : custom property. Souvent les deux, reliés.
@extend ou mixin ?Mixin = duplication contrôlée. @extend fusionne des sélecteurs — parfois plus léger, parfois illisible. Beaucoup d’équipes évitent @extend pour limiter les surprises.
Oui, surtout avec nesting CSS, variables, et quelques utilities. Les mixins restent confortables pour media queries et patterns a11y partagés.
Non pour débuter. sass:color et sass:math aident sur des systèmes mûrs — avec contrôle qualité (contraste, arrondis).
Includes ciblés, utilities générées volontairement petites, revue du CSS de prod, suppression des maps « encyclopédiques ».
Variables et mixins SCSS accélèrent un design system quand ils sont sobres, nommés pour l’usage, et reliés à une vraie stratégie de tokens (souvent complétée par des custom properties). Ils deviennent une dette quand tout passe par un mixin géant ou une liste de variables mortes.
Factorisez après avoir vu la répétition, vérifiez le CSS généré, et protégez focus et contrastes. Pour prolonger ces gestes dans un parcours clair, Academy Yunt est le bon prochain pas.