Variables CSS (Custom Properties) : Le Guide Complet pour un CSS Maintenable

Variables CSS (Custom Properties) : Le Guide Complet pour un CSS Maintenable

Introduction aux variables CSS

Les variables CSS, officiellement appelées custom properties, permettent de stocker des valeurs réutilisables dans vos feuilles de style. Elles transforment votre CSS d'un code statique et répétitif en un système dynamique, maintenable et facilement personnalisable.

Contrairement aux variables des préprocesseurs (Sass, Less), les variables CSS sont natives, fonctionnent dans le navigateur sans compilation, et participent à la cascade CSS. C'est un outil puissant que chaque développeur front-end devrait maîtriser.

Syntaxe des variables CSS

Déclarer une variable

/* Les variables sont préfixées par -- */
:root {
    --color-primary: #3498db;
    --color-secondary: #2ecc71;
    --color-text: #333333;
    --color-bg: #ffffff;
    --font-main: 'Inter', sans-serif;
    --font-size-base: 16px;
    --spacing-sm: 0.5rem;
    --spacing-md: 1rem;
    --spacing-lg: 2rem;
    --radius-sm: 4px;
    --radius-md: 8px;
    --radius-lg: 16px;
    --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.15);
    --transition-fast: 0.15s ease;
    --transition-normal: 0.3s ease;
}

Utiliser une variable

/* La fonction var() lit la valeur de la variable */
.button {
    background-color: var(--color-primary);
    color: var(--color-bg);
    padding: var(--spacing-sm) var(--spacing-md);
    border-radius: var(--radius-md);
    font-family: var(--font-main);
    box-shadow: var(--shadow-sm);
    transition: all var(--transition-fast);
}

/* Valeur de repli (fallback) */
.card {
    padding: var(--spacing-card, 1.5rem);
    /* Si --spacing-card n'existe pas, utilise 1.5rem */
}

/* Fallback en cascade */
.text {
    color: var(--color-accent, var(--color-primary, blue));
}

Portée et cascade des variables CSS

Variables globales vs locales

/* Variables globales (accessibles partout) */
:root {
    --color-primary: #3498db;
    --color-bg: #ffffff;
}

/* Variables locales (limitées à un sélecteur) */
.dark-section {
    --color-bg: #1a1a2e;
    --color-text: #e0e0e0;
}

/* Les enfants de .dark-section hériteront des nouvelles valeurs */
.dark-section .card {
    background: var(--color-bg); /* #1a1a2e, pas #ffffff */
    color: var(--color-text);    /* #e0e0e0 */
}

/* Variables de composant */
.btn {
    --btn-bg: var(--color-primary);
    --btn-color: white;
    --btn-padding: 0.75rem 1.5rem;
    --btn-radius: var(--radius-md);

    background: var(--btn-bg);
    color: var(--btn-color);
    padding: var(--btn-padding);
    border-radius: var(--btn-radius);
}
/* Variantes par simple redéfinition */
.btn-danger {
    --btn-bg: #e74c3c;
}
.btn-success {
    --btn-bg: #27ae60;
}
.btn-outline {
    --btn-bg: transparent;
    --btn-color: var(--color-primary);
}

Dark mode avec les variables CSS

/* Thème clair (défaut) */
:root {
    --color-bg: #ffffff;
    --color-bg-secondary: #f8f9fa;
    --color-text: #1a1a2e;
    --color-text-muted: #6c757d;
    --color-border: #dee2e6;
    --color-primary: #3498db;
    --color-primary-hover: #2980b9;
    --shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

/* Thème sombre (media query automatique) */
@media (prefers-color-scheme: dark) {
    :root {
        --color-bg: #0f0f23;
        --color-bg-secondary: #1a1a2e;
        --color-text: #e8e8e8;
        --color-text-muted: #9ca3af;
        --color-border: #2d2d44;
        --color-primary: #60a5fa;
        --color-primary-hover: #93c5fd;
        --shadow: 0 2px 10px rgba(0, 0, 0, 0.4);
    }
}

/* Ou avec un toggle classe (JavaScript) */
[data-theme="dark"] {
    --color-bg: #0f0f23;
    --color-bg-secondary: #1a1a2e;
    --color-text: #e8e8e8;
    --color-text-muted: #9ca3af;
    --color-border: #2d2d44;
    --color-primary: #60a5fa;
    --shadow: 0 2px 10px rgba(0, 0, 0, 0.4);
}

/* Les composants s'adaptent automatiquement */
body {
    background-color: var(--color-bg);
    color: var(--color-text);
}
.card {
    background: var(--color-bg-secondary);
    border: 1px solid var(--color-border);
    box-shadow: var(--shadow);
}
a { color: var(--color-primary); }
a:hover { color: var(--color-primary-hover); }

Toggle dark mode en JavaScript

// JavaScript pour le toggle
const toggle = document.querySelector('.theme-toggle');
const html = document.documentElement;

// Charger la préférence sauvegardée
const saved = localStorage.getItem('theme');
if (saved) html.setAttribute('data-theme', saved);

toggle.addEventListener('click', () => {
    const current = html.getAttribute('data-theme');
    const next = current === 'dark' ? 'light' : 'dark';
    html.setAttribute('data-theme', next);
    localStorage.setItem('theme', next);
});

Design System avec les variables CSS

/* === DESIGN SYSTEM TOURAK DIGITAL === */
:root {
    /* Couleurs */
    --color-primary-50: #eff6ff;
    --color-primary-100: #dbeafe;
    --color-primary-200: #bfdbfe;
    --color-primary-300: #93c5fd;
    --color-primary-400: #60a5fa;
    --color-primary-500: #3b82f6;
    --color-primary-600: #2563eb;
    --color-primary-700: #1d4ed8;
    --color-primary-800: #1e40af;
    --color-primary-900: #1e3a8a;

    /* Typographie */
    --font-sans: 'Inter', system-ui, sans-serif;
    --font-mono: 'Fira Code', monospace;
    --text-xs: 0.75rem;
    --text-sm: 0.875rem;
    --text-base: 1rem;
    --text-lg: 1.125rem;
    --text-xl: 1.25rem;
    --text-2xl: 1.5rem;
    --text-3xl: 1.875rem;
    --text-4xl: 2.25rem;

    /* Espacement */
    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-6: 1.5rem;
    --space-8: 2rem;
    --space-12: 3rem;
    --space-16: 4rem;

    /* Breakpoints (en tant que référence) */
    --bp-sm: 576px;
    --bp-md: 768px;
    --bp-lg: 992px;
    --bp-xl: 1200px;

    /* Z-index scale */
    --z-dropdown: 100;
    --z-sticky: 200;
    --z-modal-backdrop: 300;
    --z-modal: 400;
    --z-tooltip: 500;
    --z-toast: 600;
}

Techniques avancées

Variables CSS et calc()

:root {
    --base-size: 16px;
    --scale: 1.25;
}

h1 { font-size: calc(var(--base-size) * var(--scale) * var(--scale) * var(--scale)); }
h2 { font-size: calc(var(--base-size) * var(--scale) * var(--scale)); }
h3 { font-size: calc(var(--base-size) * var(--scale)); }
p  { font-size: var(--base-size); }

/* Espacement dynamique */
.container {
    --container-padding: clamp(1rem, 5vw, 3rem);
    padding-inline: var(--container-padding);
}

Variables CSS modifiées par JavaScript

// Modifier une variable CSS depuis JS
document.documentElement.style.setProperty('--color-primary', '#e74c3c');

// Lire une variable CSS
const primary = getComputedStyle(document.documentElement)
    .getPropertyValue('--color-primary').trim();

// Exemple : couleur dynamique basée sur le scroll
window.addEventListener('scroll', () => {
    const hue = (window.scrollY / 5) % 360;
    document.documentElement.style.setProperty('--dynamic-hue', hue);
});

Variables CSS vs variables Sass

CritèreVariables CSSVariables Sass ($)
CompilationNatives, pas de buildCompilées en valeurs statiques
CascadeParticipent à la cascadePas de cascade
Modification JSOui, dynamiquesNon, statiques
Media queriesRedéfinissables dans @mediaPas dynamiques
Dark modeSimple redéfinitionNécessite des mixins
PerformanceCalcul au runtimeValeurs figées au build
RecommandationPréférez pour les thèmes et les valeurs dynamiquesPréférez pour les calculs complexes au build

Bonnes pratiques

  • Nommez vos variables sémantiquement : --color-primary plutôt que --blue.
  • Utilisez :root pour les variables globales et des sélecteurs spécifiques pour les variables locales.
  • Créez une échelle de valeurs pour les couleurs (50 à 900) et les espacements.
  • Prévoyez le dark mode dès le départ en utilisant des variables pour toutes les couleurs.
  • Documentez vos variables dans un fichier dédié (variables.css ou tokens.css).
  • Utilisez des fallbacks pour la compatibilité : color: var(--primary, #3498db);

Conclusion

Les variables CSS sont un pilier du développement front-end moderne. Elles rendent votre code plus maintenable, facilitent la création de thèmes et de design systems, et permettent des personnalisations dynamiques impossibles avec les préprocesseurs seuls.

Chez Tourak Digital, nous construisons des design systems robustes basés sur les variables CSS. Contactez-nous pour un projet web maintenable et évolutif.

SEO Création Web Google Ads Marketing Blog À propos
Liens rapides
Informations
Tourak Digital Group