5213 sujets

Le Bar du forum

Bonjour à tous,

Bien sûr, il existe des enquêtes Stack Overflow, des npm trends et autres outils statistiques, mais pour vous-même : Vous utilisez quoi aujourd'hui comme outils de build pour vos styles ? Si vous en utilisez encore un d'ailleurs ? Et surtout pour quels types de projets (projet perso, d'envergure, legacy, etc) ?

Et ce qui m'intéresse le plus : quelles sont les fonctionnalités dont vous ne pouvez encore vous passer en 2026 ?

Pour vous inciter à répondre je commence par répondre moi-même à ma propre question :

Après avoir longtemps utilisé Stylus, désormais totalement legacy, n'avoir jamais été convaincu par le monolithe Sass, j'ai tenté PostCSS. Ce dernier vendait du rêve sur le papier, avançait sa modularité, mais dans la pratique il repose entièrement sur un écosystème composés de plugins tous autant chaotiques les uns que les autres : incompatibles entre eux souvent, deprecated du jour au lendemain. J'ai fini par adopter une solution maison, avec notamment Lightningcss.

Les avancés de CSS de ces 2 dernières années ont fait reculer le besoin viscéral d'avoir un préprocesseurs sur certains projets. Cependant, voici les fonctionnalités dont je ne peux me passer même aujourd'hui :

- Les variables : en effet, les custom properties ne seront jamais supportés par les media queries (@media) en raison du risque de récursivité infinie ; les @custom-media ne sont pas encore supportées et, de toute façon ne seront jamais supportés eux non plus par @container. Perso j'ai fait un système de variables qui supporte la syntaxe media queries level 5 **.
- Les mixins (@mixin et @include), mais je ne permet pas de descendre au-delà de 3 niveaux de récursivité, sinon je considère qu'il y a un problème de design ; en réalité, je devrais même interdire la récursivité pour cette feature...
- Fusion des @import, avec compatibilité layer(), en un unique fichier.
- Les boucles @for, à utiliser avec modération pour ne pas générer n'importe quoi.

Voilà, je crois que je n'ai rien oublié, j'ajouterais peut-être à terme la résolution de calc() sur les valeurs statiques, mais je ne permettrais pas les mélanges d'unités statiques comme le permet SASS, là encore je trouve que cela encourage les mauvais designs.

C'est à vous !

---

** Exemple :
$from-s-to-m: (50em < width <= 70em);

Modifié par Olivier C (02 Sep 2026 - 08:54)
Modérateur
Salut Olivier,

De mon côté, je reste assez pragmatique et mes outils s'articulent autour de ViteJS comme bundler.

Pour le reste, ma stratégie dépend de la taille du projet :

- Projets légers / relativement moyens : Du CSS natif pur. Les évolutions récentes (nesting, custom properties, @layer, etc.) suffisent amplement dans 80 % des cas aujourd'hui.
- Gros projets / architectures complexes : Je reste fidèle à Sass.

Pourquoi Sass sur de grosses architectures alors que le natif a tant progressé ? Principalement pour sa puissance algorithmique que le CSS natif ne peut remplacer :

- @if et @for : Indispensables dès qu'il s'agit de générer des grilles, des échelles typographiques ou des utilitaires dynamiques.
- @mixin et @include : Pour encapsuler des motifs complexes sans répéter de code.
- @function : Pour traiter de la donnée, manipuler des couleurs ou calculer des échelles dynamiques directement à la compilation.

Côté méthodologie et organisation du code, j'utilise deux approches (suivant le projet) :

- L'Atomic Design pour la découpe composant/système de design.
- CUBE CSS (merci d'ailleurs à Raphaël pour la découverte de cette méthodologie).
Modifié par Niuxe (02 Sep 2026 - 01:34)
Effectivement, j'avais oublié ce sujet d'il y a 9 mois...
Je vous remercie messieurs.

Niuxe, si tu as le temps de poster un exemple concret pour l'utilisation de @if et @else je suis preneur. Chez moi je n'arrive pas à trouver de cas où leurs utilisations seraient pertinentes.
Modérateur
Olivier C a écrit :
Effectivement, j&apos;avais oublié ce sujet d&apos;il y a 9 mois...
Je vous remercie messieurs.

Niuxe, si tu as le temps de poster un exemple concret pour l&apos;utilisation de @if et @else je suis preneur. Chez moi je n&apos;arrive pas à trouver de cas où leurs utilisations seraient pertinentes.


Yep, Smiley smile
Prenons cet exemple concret :
Tu dois créer un design systeme. tu veux une mixin simple pour appliquer des ombres (box-shadow), mais qui adapte son rendu si l'élément est sur fond sombre ou fond clair :


// Une map de configurations
$shadow-levels: (
  1: 0 2px 4px rgba(0, 0, 0, 0.1),
  2: 0 4px 8px rgba(0, 0, 0, 0.15),
  3: 0 8px 16px rgba(0, 0, 0, 0.2)
);

@mixin elevation($level: 1, $theme: 'light') {
  // vérifie le niveau demandé
  @if map-has-key($shadow-levels, $level) {
    
    // Traitement conditionnel selon le thème
    @if $theme == 'dark' {
      // Sur fond sombre, l'ombre noire ne se voit pas : ajoute une lueur (glow)
      box-shadow: map-get($shadow-levels, $level), 0 0 12px rgba(255, 255, 255, 0.05);
    } @else if $theme == 'light' {
      // Ombre classique pour fond clair
      box-shadow: map-get($shadow-levels, $level);
    } @else {
      @error "Le thème '#{$theme}' n'existe pas. Utilisez 'light' ou 'dark'.";
    }

  } @else {
    @warn "Niveau d'élévation invalide : #{$level}.";
  }
}

// --- Utilisation dans tes composants ---

.card {
  @include elevation(2, 'light');
}

.modal-dark {
  @include elevation(3, 'dark');
}


En CSS natif, tu devrais soit multiplier les classes utilitaires, soit répéter tes box-shadow à la main partout. .

À noter que la map peut être générée avec un @for :


@use "sass:map";
@use "sass:math";

// initialise une map vide
$shadow-levels: ();

// remplit dynamiquement avec la boucle @for
@for $i from 1 through 5 {
  $offset-y: $i * 2px;
  $blur: $i * 4px;
  $alpha: 0.05 + ($i * 0.05); // L'opacité augmente à chaque palier
  
  $shadow-value: 0 $offset-y $blur rgba(0, 0, 0, $alpha);

  // fusionne la nouvelle clé/valeur dans la map
  $shadow-levels: map.merge($shadow-levels, ($i: $shadow-value));
}


* je ne retrouve pas le fichier. Le code a été fait de tête. Je peux m'être trompé. C'est une piste à suivre dans le cas d'utilisation
Modifié par Niuxe (03 Sep 2026 - 15:15)
Pour @if je comprends, mais tu vois, pour ce cas d'usage précis, celui donné dans l'exemple, j'opterais pour une approche vanilla CSS tout de même :

:root {
  color-scheme: light dark;

  --shadow-core-1: 0 2px 4px rgba(0, 0, 0, 0.1);
  --shadow-core-2: 0 4px 8px rgba(0, 0, 0, 0.15);
  --shadow-core-3: 0 8px 16px rgba(0, 0, 0, 0.2);

  --shadow-glow-dark: 0 0 12px rgba(255, 255, 255, 0.05);

  /* Thème clair par défaut */
  --elevation-1: var(--shadow-core-1);
  --elevation-2: var(--shadow-core-2);
  --elevation-3: var(--shadow-core-3);
}

@media (prefers-color-scheme: dark) {
  :root {
      /* Concaténation de ombre + Lueur */
      --elevation-1: var(--shadow-core-1), var(--shadow-glow-dark);
      --elevation-2: var(--shadow-core-2), var(--shadow-glow-dark);
      --elevation-3: var(--shadow-core-3), var(--shadow-glow-dark);
  }
}

.card {
  box-shadow: var(--elevation-2);
}

.modal {
  box-shadow: var(--elevation-3);
}

Petit bonus ici : Le composant .card ignore totalement s'il est en thème clair ou sombre. Il n'a pas besoin de la classe utilitaire .modal-dark. Il demande le "niveau 2", et le pipeline CSS lui fournit la donnée exacte pré-calculée à la racine.

---

Tout ça m'a titillé alors j'ai cherché : apparemment, l'intérêt de @if de nos jours serait de supprimer du code mort, en ciblant la plateforme qui devra supporter l'application.
On pourrait alors faire par exemple :

@if $target-profile == 'embedded' {
  // Un fallback pour du legacy :
  border: 1px solid rgba(0, 0, 0, 0.15);
  background-color: #ffffff;
} @else {
  // Pour le support standard :
  background-color: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(#{$depth}px);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  will-change: transform;
}

Donc, quelque chose d'externe à la logique du code ; c'est un invariant très fort pour moi, et suffisant pour que j'apprenne à m'en passer pour l'instant si le CSS vanilla est suffisant.

---

Pour la boucle @for par contre, je suis convaincu moi aussi par le besoin, je l'ai intégré à mon pipeline d'ailleurs. MAIS : je l'utilise de façon naïve, juste des itérations avec i :
.demo-items-color {
  $demoColorDeg: 15;
  $demoColorDeviation: 7;

  @for $i from 1 to 15 {
    & > :nth-child($(i)n) {
      background-color: hsl(calc($i * $demoColorDeviation - $demoColorDeviation + $demoColorDeg),
          100%,
          50%);
    }
  }
}

Cela me fait prendre conscience d'une chose : il manque à mon pipeline une résolution AOT de calc() lorsque cela est possible, résolution que fait un plugin comme PostCSS Calc :

/* Avant : */
h1 {
  font-size: calc(16px * 2);
  height: calc(100px - 2em);
  width: calc(2 * var(--base-width));
  margin-bottom: calc(16px * 1.5);
}


/* Après : */
h1 {
  font-size: 32px;
  height: calc(100px - 2em);
  width: calc(2 * var(--base-width));
  margin-bottom: 24px;
}

Il faudra donc que j'ajoute cette fonctionnalité à mon pipeline. Rien que pour avoir trouvé l'importance builder calc() lorsque c'est possible (mon intuition initiale, mais je ne l'avais pas mise en œuvre) ça valait le coup de vous poser la question sur le forum. Je vous remercie pour cela.

Bonne soirée à vous.
Modifié par Olivier C (04 Sep 2026 - 13:05)