Bonnes pratiques
Les règles d'or pour un code SCSS propre et maintenable.
Imagine : tu es un maître artisan qui a forgé des centaines d'armes magiques. Après toutes ces années, tu connais parfaitement les techniques qui font la différence entre une épée ordinaire et une lame légendaire. Les bonnes pratiques SCSS, c'est pareil : ce sont les techniques éprouvées qui transforment un code fonctionnel en chef-d'œuvre maintenable et élégant.
11.1Organisation des fichiers
Une architecture claire, c'est la base de tout projet SCSS réussi. Voici la structure recommandée selon la méthodologie 7-1 pattern :
styles/
├── abstracts/
│ ├── _variables.scss (couleurs, espacements...)
│ ├── _mixins.scss (fonctions réutilisables)
│ └── _functions.scss (calculs personnalisés)
├── vendors/
│ ├── _normalize.scss (resets CSS)
│ └── _bootstrap.scss (libs externes)
├── base/
│ ├── _base.scss (styles de base)
│ ├── _typography.scss (polices et textes)
│ └── _utilities.scss (classes utilitaires)
├── layout/
│ ├── _header.scss (en-tête)
│ ├── _footer.scss (pied de page)
│ ├── _sidebar.scss (barre latérale)
│ └── _grid.scss (grille)
├── components/
│ ├── _buttons.scss (boutons)
│ ├── _cards.scss (cartes)
│ ├── _forms.scss (formulaires)
│ └── _modals.scss (modales)
├── pages/
│ ├── _home.scss (page d'accueil)
│ ├── _contact.scss (page contact)
│ └── _about.scss (page à propos)
├── themes/
│ ├── _dark.scss (thème sombre)
│ └── _admin.scss (thème admin)
└── main.scss (fichier principal)Le fichier main.scss importe tout dans le bon ordre :
// 1. Configuration et utilitaires
@use 'abstracts/variables';
@use 'abstracts/functions';
@use 'abstracts/mixins';
// 2. Vendors et resets
@use 'vendors/normalize';
// 3. Base styles
@use 'base/base';
@use 'base/typography';
@use 'base/utilities';
// 4. Layout components
@use 'layout/header';
@use 'layout/footer';
@use 'layout/grid';
// 5. Reusable components
@use 'components/buttons';
@use 'components/cards';
@use 'components/forms';
// 6. Page-specific styles
@use 'pages/home';
@use 'pages/contact';
// 7. Themes (optionnel)
@use 'themes/dark';11.2Nommage des variables
Des noms de variables clairs évitent bien des confusions. Utilise une convention cohérente :
// ❌ Noms vagues
$blue: #3498db;
$big: 2rem;
$fast: 0.2s;
// ✅ Noms expressifs par usage
$color-primary: #3498db;
$color-primary-dark: #2980b9;
$color-primary-light: #85c1e9;
$text-heading: 2rem;
$text-body: 1rem;
$text-small: 0.875rem;
$duration-fast: 0.2s;
$duration-normal: 0.3s;
$duration-slow: 0.5s;
// ✅ Encore mieux : système de design tokens
$colors: (
primary: (
50: #eff6ff,
500: #3b82f6,
900: #1e3a8a
),
gray: (
100: #f3f4f6,
500: #6b7280,
900: #111827
)
);
$spacing: (
xs: 0.25rem,
sm: 0.5rem,
md: 1rem,
lg: 1.5rem,
xl: 3rem
);11.3Écriture des sélecteurs
Quelques règles simples pour des sélecteurs maintenables :
Règle des 3 niveaux
Ne dépasse jamais 3 niveaux d'imbrication. Au-delà, ton CSS devient trop spécifique et difficile à override.// ❌ Trop profond (4 niveaux)
.page {
.content {
.section {
.card {
.title {
font-size: 1.5rem; // Trop spécifique !
}
}
}
}
}
// ✅ Restructuré et plus lisible
.page-content {
padding: 2rem;
}
.section-card {
margin-bottom: 2rem;
.card-title {
font-size: 1.5rem;
}
.card-body {
padding: 1rem;
}
}11.4Utilisation responsable des mixins
Les mixins, c'est puissant, mais ça peut vite déraper si on en abuse :
// ❌ Mixin trop spécifique
@mixin red-button-with-shadow-and-hover {
background: red;
color: white;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
&:hover {
background: darkred;
}
}
// ✅ Mixins modulaires et réutilisables
@mixin button-base {
padding: 0.75rem 1.5rem;
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: 500;
transition: all 0.2s ease;
}
@mixin button-variant($bg-color) {
background: $bg-color;
color: color.mix(white, $bg-color, 90%);
&:hover {
background: color.adjust($bg-color, $lightness: -10%);
}
}
@mixin shadow($level: 1) {
@if $level == 1 {
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
} @else if $level == 2 {
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
} @else if $level == 3 {
box-shadow: 0 10px 25px rgba(0,0,0,0.15);
}
}
// Usage propre et flexible
.btn-primary {
@include button-base;
@include button-variant(#3498db);
@include shadow(2);
}11.5Gestion des media queries
Centralise tes breakpoints pour une approche cohérente :
// Variables de breakpoints
$breakpoints: (
mobile: 480px,
tablet: 768px,
desktop: 1024px,
wide: 1200px
);
// Mixin pour les media queries
@mixin respond-to($breakpoint) {
@if map-has-key($breakpoints, $breakpoint) {
@media (min-width: map-get($breakpoints, $breakpoint)) {
@content;
}
} @else {
@warn "Breakpoint '#{$breakpoint}' non défini dans $breakpoints.";
}
}
// Usage propre
.hero {
padding: 2rem;
@include respond-to(tablet) {
padding: 4rem;
}
@include respond-to(desktop) {
padding: 6rem;
}
}11.6Commentaires et documentation
Un code bien documenté, c'est un cadeau pour ton futur toi (et tes collègues) :
/**
* COMPOSANT : Card
*
* Carte polyvalente utilisée dans :
* - Liste des articles (blog)
* - Grille de produits (shop)
* - Dashboard admin
*
* Variantes disponibles :
* - .card--elevated (avec ombre)
* - .card--bordered (avec bordure)
* - .card--compact (version réduite)
*/
.card {
background: white;
border-radius: 8px;
overflow: hidden;
transition: transform 0.2s ease;
// Variante avec élévation
&--elevated {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
&:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}
}
// En-tête de la carte
&__header {
padding: 1.5rem;
border-bottom: 1px solid #eee;
}
// Titre dans l'en-tête
&__title {
margin: 0;
font-size: 1.25rem;
font-weight: 600;
color: #2c3e50;
}
}11.7Optimisation des performances
Quelques astuces pour un CSS final plus léger et plus rapide :
Évite les sélecteurs complexes
Plus un sélecteur est complexe, plus le navigateur met de temps à l'analyser. Privilégie les classes simples.// ❌ Sélecteur lourd
.sidebar .widget:not(.widget--hidden) > .widget-content .title:first-child {
font-weight: bold;
}
// ✅ Classe dédiée plus performante
.widget-title--primary {
font-weight: bold;
}
// ❌ Beaucoup de propriétés répétées
.btn-small { padding: 0.5rem 1rem; border-radius: 4px; font-size: 0.875rem; }
.btn-medium { padding: 0.75rem 1.5rem; border-radius: 4px; font-size: 1rem; }
.btn-large { padding: 1rem 2rem; border-radius: 4px; font-size: 1.125rem; }
// ✅ Utilise les placeholders pour partager les styles communs
%btn-base {
border-radius: 4px;
border: none;
cursor: pointer;
transition: all 0.2s ease;
}
.btn-small { @extend %btn-base; padding: 0.5rem 1rem; font-size: 0.875rem; }
.btn-medium { @extend %btn-base; padding: 0.75rem 1.5rem; font-size: 1rem; }
.btn-large { @extend %btn-base; padding: 1rem 2rem; font-size: 1.125rem; }11.8Éviter les anti-patterns
Quelques erreurs courantes à éviter absolument :
// ❌ ANTI-PATTERN : Modifications directes des vendors
// Ne modifie JAMAIS directement les fichiers de librairies !
@use 'bootstrap/scss/bootstrap'; // ✅ OK
.btn { color: red !important; } // ❌ Évite !important
// ✅ BONNE PRATIQUE : Override propre
.btn-custom {
@extend .btn;
color: red;
// ou utilise des variables Bootstrap
}
// ❌ ANTI-PATTERN : Variables magiques
.card {
margin: 23px; // D'où vient ce 23 ?
padding: 17px; // Et ce 17 ?
}
// ✅ BONNE PRATIQUE : Variables nommées
$card-margin: 1.5rem;
$card-padding: 1rem;
.card {
margin: $card-margin;
padding: $card-padding;
}
// ❌ ANTI-PATTERN : Trop de nesting avec des sélecteurs d'éléments
.article {
h1 {
h2 {
a {
span {
// Évite ça !
}
}
}
}
}
// ✅ BONNE PRATIQUE : Classes explicites
.article-title { /* styles pour h1 */ }
.article-subtitle { /* styles pour h2 */ }
.article-link { /* styles pour a */ }11.9Tests et validation
Vérifie régulièrement la qualité de ton code SCSS :
- Linter SCSS : Utilise stylelint avec des règles SCSS pour détecter les erreurs
- Outils de build : Vérifie que ta compilation ne génère pas d'erreurs
- Performance : Analyse la taille de ton CSS final
- Tests visuels : Vérifie sur différents navigateurs et tailles d'écran
Astuce
Configure ton éditeur avec des extensions SCSS (coloration syntaxique, autocomplétion, vérification d'erreurs en temps réel). Ton IDE peut devenir ton meilleur allié pour éviter les erreurs courantes !