Personnalisation dynamique des thèmes dans une interface Web Flask avec variables CSS

Introduction

Lorsqu’un service Web basé sur un modèle d’IA comme Qwen-Image-2512-SDNQ est déployé, l’interface utilisateur reste souvent statique. Pourtant, offrir une expérience visuelle adaptable — que ce soit pour les développeurs préférant le mode sombre ou les designers appréciant les interfaces claires — améliore significativement l’ergonomie.

Cet article explique comment implémenter un système de thèmes dynamiques dans une application Flask, en utilisant les variables CSS modernes, tout en permettant aux utilisateurs de personnaliser leur interface et de conserver leurs préférences.

Les variables CSS : fondation d’une interface modulaire

Les variables CSS (ou propriétés personnalisées) permettent de centraliser les valeurs réutilisables telles que les couleurs, les polices ou les espacements :

:root {
  --main-bg: #ffffff;
  --text-color: #212529;
}

body {
  background-color: var(--main-bg);
  color: var(--text-color);
}

Avantages clés :

  • Maintenance simplifiée : modification globale via une seule valeur
  • Consistance visuelle à travers tous les composants
  • Changement dynamique possible via JavaScript
  • Compatibilité universelle avec les navigateurs modernes

Architecture du système de thèmes

Structure des fichiers

Créez un fichier static/css/themes.css contenant les définitions de thèmes :

/* Variables partagées */
:root {
  --radius: 8px;
  --shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  --font-base: -apple-system, BlinkMacSystemFont, sans-serif;
}

/* Thème clair */
[data-theme="light"] {
  --bg-main: #ffffff;
  --bg-secondary: #f8f9fa;
  --text-primary: #212529;
  --border-color: #dee2e6;
  --primary: #007bff;
  --primary-hover: #0056b3;
}

/* Thème sombre */
[data-theme="dark"] {
  --bg-main: #121212;
  --bg-secondary: #1e1e1e;
  --text-primary: #e9ecef;
  --border-color: #495057;
  --primary: #0d6efd;
  --primary-hover: #0b5ed7;
}

/* Thème vert (reposant) */
[data-theme="green"] {
  --bg-main: #f0f9f5;
  --bg-secondary: #e8f5f0;
  --text-primary: #2d4a3c;
  --border-color: #c8e6d4;
  --primary: #20c997;
  --primary-hover: #199d76;
}

Migration du style existent

Remplacez les valeurs fixes dans votre feuille de style principale par des variables :

.card {
  background: var(--bg-main);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.btn-primary {
  background-color: var(--primary);
  border-color: var(--primary);
}
.btn-primary:hover {
  background-color: var(--primary-hover);
}

Implémentation du sélecteur de thème

Interface utilisateur

Ajoutez un menu déroulant dans votre template HTML (templates/index.html) :

<div class="theme-selector">
  <label>Thème :</label>
  <select id="theme-picker">
    <option value="light">Clair</option>
    <option value="dark">Sombre</option>
    <option value="green">Vert</option>
    <option value="custom">Personnalisé</option>
  </select>

  <div id="custom-panel" style="display:none;">
    <input type="color" id="custom-primary" value="#007bff">
    <input type="color" id="custom-bg" value="#ffffff">
    <button id="apply-custom">Appliquer</button>
  </div>
</div>

Gestion dynamique avec JavaScript

Utilisez une classe pour gérer les thèmes :

class ThemeController {
  constructor() {
    this.select = document.getElementById('theme-picker');
    this.customPanel = document.getElementById('custom-panel');
    this.loadPreferences();
    this.bindEvents();
  }

  loadPreferences() {
    const saved = localStorage.getItem('app-theme') || 'light';
    this.setTheme(saved);
    this.select.value = saved;
    if (saved === 'custom') this.customPanel.style.display = 'block';
  }

  bindEvents() {
    this.select.addEventListener('change', e => {
      const theme = e.target.value;
      if (theme === 'custom') {
        this.customPanel.style.display = 'block';
      } else {
        this.customPanel.style.display = 'none';
        this.setTheme(theme);
        localStorage.setItem('app-theme', theme);
      }
    });

    document.getElementById('apply-custom').addEventListener('click', () => {
      const root = document.documentElement;
      root.style.setProperty('--primary', document.getElementById('custom-primary').value);
      root.style.setProperty('--bg-main', document.getElementById('custom-bg').value);
      localStorage.setItem('app-theme', 'custom');
    });
  }

  setTheme(name) {
    document.documentElement.setAttribute('data-theme', name);
  }
}

document.addEventListener('DOMContentLoaded', () => new ThemeController());

Transitions fluides

Ajoutez des animations CSS pour adoucir les changements :

* {
  transition: background-color 0.3s, color 0.3s, border-color 0.3s;
}
img, video, canvas { transition: none; }

Fonctionnalités avancées

Suivi du thème système

Si aucun thème n’est défini manuellement, adaptez-vous au mode système :

const prefersDark = window.matchMedia('(prefers-color-scheme: dark)');
if (!localStorage.getItem('app-theme')) {
  const initial = prefersDark.matches ? 'dark' : 'light';
  this.setTheme(initial);
}

Configuration étendue

Pour une personnalisation plus fine, ajoutez des curseurs pour les rayons, ombres, etc., en liant chaque contrôle à une varible CSS via data-var="--nom-variable", puis mettez à jour dynamiquement avec document.documentElement.style.setProperty().

Cas d’usage pratiques

  • Profils utilisateurs : appliquez des thèmes prédéfinis selon le rôle (développeur, designer).
  • Changement horaire : bascule automatique vers le thème sombre entre 18h et 6h.
  • Export/import : sauvegardez la configuration personnalisée en JSON pour la partager.

Étiquettes: Flask CSS Variables theming JavaScript WebUI

Publié le 8 août à 07h38