Passer à PostCSS pour un projet sans SASS
Cela fait plusieurs années que nous avons l’habitude d’utiliser le préprocesseur SASS (Syntactically Awesome Style Sheets) chez JoliCode. Incontournable chez les intégrateur·rice·s, il permet d’utiliser des variables, faire des boucles, créer des mixins…
Mais avec les avancées du langage CSS qui permet d’utiliser des custom properties et bientôt de faire de l’imbrication, la pertinence de son utilisation commence à se poser. J’avoue, à titre personnel, être très adepte du « pourquoi changer si ça fonctionne ? » J’aime mes petites habitudes, mon confort et j’ai un peu peur d’être frustrée en changeant d’outil.
Un de mes collègues a travaillé sur un nouveau gabarit de projet Symfony qui utilise PostCSS mais se passe de SASS. Lorsque j’ai eu l’opportunité de travailler sur le site cacharel.fr, un petit projet de quelques pages, je me suis alors dit qu’il était peut-être temps pour moi de sortir un peu de ma zone de confort et d’expérimenter un projet sans SASS.
Section intitulée c-est-quoi-postcssC’est quoi PostCSS ?
J’utilise déjà PostCSS depuis de nombreuses années. Il me permet a minima d’utiliser autoprefixer pour ajouter les préfixes CSS qui vont bien sur les règles encore peu supportées par les navigateurs. PostCSS diffère de SASS dans le sens où SASS est un préprocesseur qui propose par défaut un certain nombre de fonctionnalités. PostCSS par défaut ne fait rien, ça n’est pas un préprocesseur, c’est un outil qui nous permet de modifier du code CSS à l’aide de JavaScript. On va pouvoir l’agrémenter de plugins pour y ajouter, par exemple, les fonctionnalités d’un préprocesseur ou encore utiliser des frameworks comme Tailwind CSS.
L’idée était donc d’utiliser PostCSS qui est déjà installé sur nos projets, pour remplacer SASS et donc se séparer d’un outil a priori superflu.
Pour utiliser PostCSS, on peut bien sûr se servir d’un outil comme Parcel, Vite ou encore webpack. Encore plus simplement, on peut utiliser postcss-cli pour pouvoir lancer postcss en ligne de commande (ou via un script npm). Dans tous les cas, PostCSS se basera sur un fichier de configuration postcss.config.js
dans lequel on indiquera l’ensemble des plugins utilisés sur notre projet.
Section intitulée ajouter-un-premier-plugin-postcss-importAjouter un premier plugin : postcss-import
L’une des fonctionnalités bien pratiques de SASS est de pouvoir diviser son code en plusieurs fichiers et de les importer à l’aide de @import
. Alors certes, CSS dispose aussi de sa propre règle @import mais celle-ci engendre des requêtes HTTP supplémentaires pour charger les différents fichiers. Heureusement le plugin postcss-import gère l’import lors de la compilation pour éviter cela (et mime donc le fonctionnement de l’import en SASS). C’est donc le premier plugin que j’ai installé :
npm install -D postcss-import
J’ai ensuite ajouté le plugin dans le fichier de configuration précédemment créé :
module.exports = {
plugins: {
'postcss-import': {}
}
}
J’ai ainsi pu séparer mon code CSS en plusieurs fichiers et les importer, comme je le fais habituellement en SASS, depuis un fichier de style principal. La librairie PostCSS me permet également d’importer des librairies depuis le dossier node_modules (comme Tailwind dans l’exemple ci dessous).
/* Fichier app.css */
/* ------ CONFIG ------ */
@import 'config/variables';
/* ------ BASE ------ */
@import 'tailwindcss/base';
@import 'base/fonts';
@import 'base/reset';
/* ------ LAYOUT ------ */
@import 'layout/header';
@import 'layout/footer';
/* ------ COMPONENTS ------ */
@import 'tailwindcss/components';
@import 'components/hero';
@import 'components/buttons';
Détail important à savoir : le plugin PostCSS se base sur le fonctionnement de la règle native CSS qui implique que la règle d’import doit être utilisée avant toute autre règle.
Section intitulée imbriquer-mes-regles-cssImbriquer mes règles CSS
La possibilité d’imbriquer des règles en SASS a sûrement été l’un des premiers effets « wahou » que j’ai eu en commençant à utiliser un préprocesseur. Si la prise en charge de l’imbrication en CSS natif fait son bonhomme de chemin, c’est encore loin d’être bien supporté et ça ne prend pas en charge l’imbrication des sélecteurs BEM. J’avoue être peu adepte de cette pratique qui ne me permet pas de pouvoir retrouver facilement un sélecteur CSS dans mon code. Cependant, je l’utilise systématiquement pour les modifier (et je vous l’ai dit, je n’aime pas changer mes habitudes).
Il existe deux plugins PostCSS pour faire de l’imbrication :
- postcss-nesting, qui se base sur le fonctionnement de l’imbrication CSS native (mais la rend compatible partout)
- postcss-nested, qui reprend plutôt le fonctionnement de l’imbrication en SASS, c’est donc celui que j’ai privilégié
Utilisant également Tailwind sur mon projet j’ai pu utiliser tailwindcss/nesting qui peut se baser sur l’un ou l’autre des deux plugins. Il permet de faire en sorte que les règles de Tailwind comme @apply
ou @screen
fonctionnent avec l’imbrication.
Section intitulée et-pour-les-mixins-et-regles-extendEt pour les mixins et règles extend ?
En installant deux plugins je me sentais déjà plus à l’aise pour travailler avec PostCSS et sans SASS. Concernant les variables il me suffisait de plutôt utiliser les custom properties en CSS.
Mais qu’en est-il des mixins ou des extend ?
Je suis peu friande de l’utilisation de la règle @extend
en SASS. Elle duplique les sélecteurs et change l’ordre, et donc la spécificité de ceux-ci dans le code CSS final. Voilà pourquoi certain·e·s intégrateur·rice·s la déconseillent. Il m’arrive par contre d’utiliser des mixins pour gagner du temps et ne pas répéter certaines règles CSS fréquentes.
Concernant la règle @extend
, le framework Tailwind me permet d’utiliser la règle @apply
. Celle-ci permet de copier les règles d’un sélecteur dans un autre (et évite donc la duplication de sélecteurs comme avec @extend
) :
@layer components {
/* Il faut absolument placer le sélecteur dont on hérite dans un layer */
.container {
width: 100%;
max-width: 144rem;
margin: 0 auto;
padding-inline: 1.6rem;
}
.small-container {
@apply container;
max-width: 97.6rem;
}
}
Bonus supplémentaire, un sélecteur présent dans un @layer
Tailwind mais qui n’est pas utilisé dans un template n’apparaitra pas dans le CSS final.
Il est également possible d’utiliser le plugin postcss-insert qui reprends ce même fonctionnement, mais attention même s’il est fonctionnel il a été archivé par son auteur et n’est plus mis à jour.
L’utilisation de @apply
m’a finalement suffit sur mon petit projet. Mais si j’avais voulu retrouver plus de fonctionnalités de SASS j’aurais pu :
- Utiliser postcss-mixins pour pouvoir créer des mixins comme en SASS
- Utiliser postcss-define-function pour pouvoir créer des fonctions
- Utiliser postcss-extend-rule pour reprendre exactement le fonctionnement de la règle SASS
@extend
Section intitulée profiter-des-dernieres-fonctionnalites-de-cssProfiter des dernières fonctionnalités de CSS
J’ai découvert qu’à l’instar de Babel pour JavaScript, PostCSS dispose d’un plugin qui permet d’utiliser les dernières fonctionnalités de CSS même si elles ne sont pas encore implémentées par les navigateurs, il s’agit de postcss-preset-env. Les nouvelles fonctionnalités de CSS sont classées selon différentes étapes (ou stages) en partant de 0 (propositions et idées ouvertes à la discussion) à 4 (fonctionnalités implémentées par la plupart des navigateurs). Le site cssdb permet de visualiser la liste de ces fonctionnalités et leur position au sein du processus d’implémentation.
Par défaut, le plugin prend en compte les fonctionnalités qui sont au moins à l’étape 2 du processus (considérées comme pertinentes mais pas encore implémentées). Mais ce paramètre est modifiable lors de l’inclusion du plugin
module.exports = {
plugins: {
'postcss-preset-env': {
stage: 2 // modifier ici si besoin l'étape minimum à cibler
}
}
}
Cela permet alors d’utiliser entre autre les custom media queries :
@custom-media --narrow-window (max-width: 30em);
@media (--narrow-window) {
/* narrow window styles */
}
Le plugin remplacera la valeur du custom media dans le CSS final puisque cette fonctionnalité n’est pas encore implémentée. L’avantage étant que lorsqu’elle le sera, il conservera simplement ce code. Il se base sur la configuration browserslist qui permet de spécifier quels navigateurs sont à prendre en charge (comme le fait le plugin autoprefixer).
Je n’ai pas forcément pensé à utiliser de nouvelles fonctionnalités sur mon projet mais j’avoue trouver ce plugin particulièrement intéressant (Serais-je en train de changer d’avis ? Peut-être…)
Section intitulée la-gestion-des-media-queriesLa gestion des media queries
J’étais déjà plutôt satisfaite des différents plugins que j’avais installés et qui me permettaient de retrouver un confort d’intégration assez similaire que lors de l’utilisation d’un préprocesseur. À un détail près : j’apprécie particulièrement la librairie include-media, une mixin SASS qui permet de simplifier l’utilisation des media queries et m’évite de me creuser la tête pour trouver des noms à mes variables et mixin (telle que mobile-only, tablet, desktop-up et autres joyeusetés) :
$breakpoints: (phone: 320px, tablet: 768px, desktop: 1024px);
@include media(">phone", "<=tablet") {
width: 50%;
}
Quelle ne fut pas ma joie de découvrir que cette mixin a été adaptée en plugin PostCSS. La subtilité est qu’il faut définir ses breakpoints dans le fichier de configuration PostCSS (en plus de les indiquer dans la configuration de Tailwind) :
module.exports = {
plugins: {
'postcss-include-media': {
breakpoints: { phone: '320px', tablet: '768px', desktop: '1024px', large: '1440px' }
},
},
};
Un maigre ajustement auquel j’étais prête à consentir (comme quoi je ne suis pas si butée que ça… 🙄).
Section intitulée un-petit-plugin-en-bonusUn petit plugin en bonus
J’avais quelques animations à intégrer et je préfère toujours, lorsque c’est possible, privilégier les animations CSS. Afin de contrôler au mieux celles-ci j’aime utiliser les courbes de easings qui vont bien plutôt que de laisser celui par défaut. J’ai donc installé le plugin postcss-easings qui me permet d’utiliser des noms pour mes fonctions de easing plutôt que d’utiliser la classique fonction cubic-bezier qui n’est pas très parlante :
/* Sans le plugin */
.block {
transition: transform 0.6s cubic-bezier(0.5, 1, 0.89, 1);
}
/* Avec le plugin */
.block {
transition: transform 0.6s easeOutQuad;
}
Section intitulée alors-convaincueAlors, convaincue ?
J’ai finalement réalisé mon intégration sans SASS et (presque) sans râler. L’écosystème PostCSS me semble suffisamment complet pour faire la transition en douceur vers une intégration sans préprocesseur. Le site de PostCSS liste les plugins disponibles et dispose d’ailleurs d’une catégorie SASS pour se passer du préprocesseur sans être totalement désemparé.
Voici à quoi ressemblait finalement mon fichier de configuration final :
module.exports = {
plugins: {
'postcss-import': {},
'tailwindcss/nesting': {},
tailwindcss: {},
autoprefixer: {},
'postcss-easings': {},
'postcss-include-media': {
breakpoints: { phone: '320px', tablet: '768px', desktop: '1024px', large: '1440px' }
},
},
};
Les avancées de CSS devraient nous permettre de nous passer petit à petit d’outils supplémentaires pour enrichir ses fonctionnalités. Passer de SASS à PostCSS semble être un premier pas en ce sens.
Commentaires et discussions
J’ai testé Tailwind CSS…
Paris 11e, un vendredi, 10h42, pause café : Greg (développeur Back-End) : Tu n’as jamais testé Tailwind CSS ? Allô, on est en 2021, même ma nièce de 2 ans s’y est mise ! Moi (développeur Front-End) : Mouais… c’est juste un générateur de classes utilitaires… mais ok, si tu insistes, …
Notre framework d’interface Atomic Builder – Partie 2
Pour de nombreux développeurs Web, utiliser Bootstrap ou Foundation est une évidence lorsqu’ils commencent le développement d’un site Web. Nous avons décidé de faire autrement. Pour nos projets, nous avons créé un outil plus léger, plus souple, plus en adéquation avec nos besoins, …
Lire la suite de l’article Notre framework d’interface Atomic Builder – Partie 2
Nos articles sur le même sujet
Nos formations sur ce sujet
Notre expertise est aussi disponible sous forme de formations professionnelles !

CSS avancé
Mettre en forme des pages web en offrant des possibilités de personnalisation poussées
Ces clients ont profité de notre expertise
Refonte complète de la plateforme d’annonces immobilières de Cushman & Wakefield France. Connecté aux outils historiques, cette nouvelle vitrine permet une bien meilleure visibilité SEO et permet la mise en avant d’actifs qui ne pouvaient pas l’être auparavant.
Discourse est un logiciel libre pour forum de discussions très puissant, sur lequel Mix with the Masters s’appuie pour créer et animer sa communauté. Nous avons appliqué une forte customisation du logiciel sur plusieurs aspects : thème graphique complet en accord avec la charte graphique du site ; plugin dédiés pour afficher un paywall ; implémentation…
Nous avons entrepris une refonte complète du site, initialement développé sur Drupal, dans le but de le consolider et de jeter les bases d’un avenir solide en adoptant Symfony. La plateforme est hautement sophistiquée et propose une pléthore de fonctionnalités, telles que la gestion des abonnements avec Stripe et Paypal, une API pour l’application…