Minifieur CSS, gratuit

Compressez du CSS en retirant commentaires et espaces, et en optimisant les valeurs.

À propos de la minification CSS

Il est tentant de supposer que parce que Brotli compresse les flux de texte avec tant d’agressivité, la valeur marginale d’une passe de minification séparée s’est effondrée. Le blog d’ingénierie de Sentry a fait exactement cet argument en avril 2024 et a conclu l’inverse : la minification rapporte toujours. Avec une vitesse internet mobile médiane mondiale autour de 53 Mbps et Brotli universellement déployé en périphérie de CDN, « si vous parvenez à raboter ne serait-ce que 1 Ko sur un total de 100 ressources à chaque chargement de page, vous pourriez gagner 15 ms sur la vitesse de votre page pour ces utilisateurs. » Multiplié par la base de visiteurs de tout site non trivial, cela devient une vraie facture de bande passante, un vrai coût en batterie sur les appareils mobiles, et un vrai changement de position sur un rapport Lighthouse.

Le mécanisme compte. Gzip et Brotli sont des compresseurs sans perte à usage général qui cherchent des séquences d’octets répétées et encodent chaque répétition comme une référence-arrière dans un dictionnaire à fenêtre glissante. Deux fichiers CSS qui produisent le même comportement de navigateur mais contiennent des octets différents se compresseront en deux tailles différentes. margin: 10px 10px 10px 10px; et margin:10px sont sémantiquement identiques, mais le premier a plus de caractères à encoder même si beaucoup sont des répétitions, Brotli est bon pour trouver la répétition mais ne comprend pas que deux chaînes CSS syntaxiquement distinctes expriment la même règle. Seul un minifieur CSS-aware peut faire cela. Le hub d’apprentissage de Cloudflare situe les réductions de texte brut typiques à 30-50 % ; Brotli par-dessus ajoute encore un modeste 5-15 %, mais ce n’est pas zéro, et à grande échelle cela s’additionne.

Le CSS bloque le rendu, et c’est pour ça que les octets comptent

Le Largest Contentful Paint est l’un des trois Core Web Vitals ; le seuil pour « Bon » est de 2,5 secondes au 75ᵉ percentile des chargements. Le score Performance global de Lighthouse pondère le LCP à 25 % du total. Le CSS bloque le rendu par défaut, quand le navigateur voit un <link rel="stylesheet">, il met le rendu en pause jusqu’à ce que le fichier soit téléchargé et que le CSSOM soit construit, parce que des règles plus loin dans la feuille de style peuvent surcharger des règles antérieures et le navigateur ne peut pas risquer de peindre dans un état non stylé ou mal stylé. Le CSS Object Model, contrairement au DOM, n’est pas construit incrémentalement, l’analyseur a besoin de toute la feuille pour savoir quelles règles l’emportent. JavaScript est aussi bloqué là-dessus : les scripts ne peuvent pas s’exécuter en toute sécurité tant que le CSSOM est incomplet. L’implication pratique est que chaque octet de CSS bloquant le rendu est sur le chemin critique de chaque Core Web Vital. Un bundle minifié de 100 Ko vous fait gagner peut-être 30 ms sur un lien 4G rapide comparé à 150 Ko non minifié, petit par page, mais l’étude de cas Vodafone a montré une augmentation de 8 % des ventes pour une amélioration de 31 % du LCP. L’effet de second ordre est encore plus grand : un LCP plus rapide augmente les scores Lighthouse, ce qui augmente la visibilité sur Google pour les sites où les Web Vitals sont un signal de classement connu.

Ce qu’un minifieur CSS fait réellement

Minifieur vs optimiseur, la ligne sûr-vs-agressif

La documentation de cssnano distingue entre son preset « default » (transformations sûres uniquement) et son preset « advanced » (transformations agressives qui dépendent d’hypothèses sur votre CSS). Le preset par défaut est ce que vous activez sans réfléchir ; le preset advanced est ce que vous activez après audit, parce que certaines optimisations peuvent casser du code qui dépend d’un comportement subtil de cascade, de préfixes vendeurs, ou de bizarreries navigateur. Les transformations advanced peuvent réordonner les règles dans une feuille pour améliorer la compressibilité, risqué si vous avez des fallbacks intentionnels de propriétés dupliquées comme display: flex; display: grid;. Elles peuvent fusionner des corps de règles identiques dans des listes de sélecteurs séparées par virgules. Elles peuvent supprimer comme code mort les déclarations qui sont écrasées, avec la même réserve sur les fallbacks. Elles peuvent normaliser les valeurs display, les fonctions de transformation et les identifiants personnalisés, translate3d(0,0,0) peut se simplifier en translate(0) si vous ne dépendez pas de l’effet de bord de promotion GPU. Elles peuvent supprimer des préfixes vendeurs inutilisés selon une cible Browserslist. csso (Yandex, 2011) se décrit comme un « optimiseur structurel » plutôt qu’un minifieur pur, avec trois catégories de transformation : nettoyage, compression et restructuration. Lightning CSS décrit le même partage : une passe « minify » qui est toujours sûre, plus un ensemble de transformations targets-aware qui compilent du CSS moderne vers ce que les navigateurs plus anciens comprennent. La ligne honnête : un minifieur est ce que vous pouvez appliquer à n’importe quel fichier CSS sans réfléchir ; un optimiseur est ce que vous appliquez avec une connaissance de votre codebase.

Brève histoire de l’outillage de minification CSS

YUI Compressor (2007). Julien Lecomte de Yahoo a annoncé YUI Compressor le 11 août 2007. La version originale ne gérait que JavaScript ; trois jours plus tard, la version 2.0 ajoutait le support CSS en intégrant un minifieur CSS basé sur regex écrit à l’origine par Isaac Schlueter pour son usage personnel. YUI Compressor a été le standard de fait pendant plusieurs années, particulièrement dans les mondes Java/Maven et Rails-asset-pipeline ; il est encore utilisé aujourd’hui, même si la bibliothèque YUI elle-même a été retirée par Yahoo en 2014. Le côté CSS de YUI Compressor a toujours été basé sur regex, pas sur AST, une décision de conception dont les conséquences résonnent dans les outils plus petits côté navigateur qui ont suivi.

clean-css (2011). Jakub Pawlowicz a publié clean-css sous l’organisation GoalSmashers sur GitHub en 2011, le présentant comme « optimiseur CSS rapide et efficace pour Node.js et le Web ». C’était le premier minifieur CSS majeur conçu spécifiquement pour l’écosystème Node.js et il est devenu le défaut dans les pipelines Grunt et Gulp. La ligne 5.x actuelle attire environ 21 millions de téléchargements hebdomadaires depuis npm, supporte le linling de @import, le rebasing d’URL et les source maps, et a un modèle « niveaux d’optimisation » à paliers qui rend explicite le partage sûr-vs-agressif. csso (2011) est né comme projet interne de Yandex, publié avec un copyright 2011 par Sergey Kryzhanovsky basé sur une idée de Vitaly Harisov. cssnano (avril 2015) par Ben Briggs a pris une approche différente : au lieu d’un seul minifieur monolithique, cssnano est un bundle organisé de petits plugins PostCSS (~30 dans le preset par défaut). Il est devenu le minifieur CSS dominant dans l’écosystème JavaScript en grande partie grâce à cette composabilité et parce que PostCSS lui-même (le framework d’Andrey Sitnik, publié pour la première fois en novembre 2013) est devenu le substrat pour tellement d’autres choses (Autoprefixer, Stylelint, le pipeline de traitement de Tailwind). cssnano est maintenant en version 7.x et est le minifieur CSS par défaut dans css-minimizer-webpack-plugin de webpack, dans Next.js, et dans beaucoup d’autres défauts de framework.

Le minifieur CSS d’esbuild (2020-2021). Evan Wallace, le co-fondateur de Figma, a publié esbuild comme « un projet de loisir que j’ai écrit pendant les vacances d’hiver 2019-2020 ». Écrit en Go, esbuild était 10-100× plus rapide que les bundlers basés sur JavaScript de l’époque. Le support CSS a mûri jusqu’en 2021 ; il est désormais omniprésent comme minifieur sous-jacent dans Vite, dans tsup, dans d’innombrables modèles de framework. Lightning CSS (2021/2022). Devon Govett, créateur de Parcel, a annoncé Parcel CSS en 2021, un analyseur, transformateur, bundler et minifieur CSS écrit de zéro en Rust. L’argumentaire était la vitesse (10-100× plus rapide que les outils JS-based en place) plus la correction (un vrai analyseur conforme à la spec CSS, pas du pattern-matching par regex) plus la compilation targets-aware (descendre du CSS moderne vers ce que les navigateurs plus anciens comprennent, comme Babel pour JavaScript). En 2022 le projet a été renommé Lightning CSS pour le dissocier de Parcel en tant qu’outil autonome. Il est désormais le pipeline CSS moderne recommandé de Vite, le défaut dans Parcel lui-même, et une option dans css-minimizer-webpack-plugin. Le moteur de nouvelle génération Oxide de Tailwind l’intègre.

Le pipeline CSS moderne

Les projets web modernes écrivent rarement du CSS brut directement dans une feuille de style. Sass (Hampton Catlin et Natalie Weizenbaum, premier release en 2006), Less (Alexis Sellier, 2009) et Stylus (TJ Holowaychuk, 2010) sont en tête de pipeline, ajoutant des variables, imbrications, mixins, fonctions et partials. Le compilateur émet du CSS vanille, qui passe ensuite par PostCSS pour des transformations comme Autoprefixer (application de préfixes vendeurs basée sur Browserslist), déballage du CSS imbriqué et descente de niveau du CSS moderne. Ce n’est qu’après tout cela que le minifieur tourne, sur le CSS aplati final. Les bundlers modernes livrent la minification CSS par défaut, webpack 5 inclut css-minimizer-webpack-plugin (cssnano sous le capot par défaut, avec cssoMinify, cleanCssMinify, esbuildMinify et lightningCssMinify tous sélectionnables) ; Vite utilise esbuild pour le CSS par défaut et supporte Lightning CSS en opt-in ; Parcel utilise Lightning CSS ; Next.js, Remix, Astro, SvelteKit et Nuxt empaquettent tous la minification dans les builds de production sans intervention du développeur. Le résultat est que pour quiconque utilise un pipeline de build moderne, la minification CSS arrive automatiquement.

Mais tout le monde n’utilise pas un pipeline de build. Plein de sites WordPress, de pages HTML écrites à la main, de sites statiques Jekyll/Hugo/Eleventy sans toolchain JS, et de projets ponctuels livrent du CSS qui n’a jamais été près de webpack. Pour ceux-là, un minifieur dans le navigateur est le chemin de moindre résistance, collez le CSS, copiez le résultat, sauvegardez le déploiement.

Critical CSS

Une technique complémentaire à connaître : critical CSS est la pratique consistant à identifier le sous-ensemble de styles nécessaires pour rendre la zone visible au-dessus de la ligne de flottaison, à intégrer ce sous-ensemble directement dans un bloc <style> dans la tête du document, et à différer le reste de la feuille de style en chargement non bloquant. Bien faite, la page peint sa fenêtre initiale au tout premier aller-retour réseau, sans aucune requête séparée pour une feuille de style externe. Filament Group a construit l’outillage canonique, Scott Jehl a publié loadCSS le 14 juillet 2014, un petit utilitaire JavaScript qui charge une feuille de style de manière asynchrone en mettant son attribut media à une valeur non concordante, puis en le rebasculant à all une fois le fichier téléchargé. Le motif est devenu suffisamment standard pour que les navigateurs ajoutent <link rel="preload" as="style" onload="this.rel='stylesheet'"> comme façon plus directe de l’exprimer. Jason Miller (créateur de Preact) a publié Critters sous GoogleChromeLabs en 2018 comme alternative plus rapide, au lieu de faire tourner un navigateur headless pour inspecter la page rendue, Critters fait de l’analyse statique. Le dépôt Critters a été archivé en 2024, le fork activement maintenu vivant désormais sous le nom Beasties, sous l’équipe Nuxt. Tous ces outils dépendent du fait que le CSS sous-jacent soit bien minifié, chaque octet économisé dans la feuille source se répercute sur un inline critique plus petit.

Les hacks d’héritage ont disparu

Les navigateurs modernes analysent tous le CSS selon la même spec. Les hacks historiques qui rendaient autrefois la minification CSS risquée ont essentiellement disparu : le hack * html ciblait IE6 en exploitant un bug d’analyseur ; le hack du soulignement _property: value ciblait IE6 et avant ; *property: value (avec * avant le nom de la propriété) ciblait IE7 et avant ; les commentaires conditionnels <!--[if IE 6]> permettaient de servir des feuilles de style différentes à des versions spécifiques d’IE, mais Microsoft a retiré cette fonctionnalité dans IE10. IE11 a atteint sa fin de vie le 15 juin 2022 pour la plupart des versions Windows 10 grand public. À partir de 2026, ces hacks sont des curiosités historiques et un minifieur CSS n’a plus à y penser. Un minifieur moderne qui retire l’espace blanc de manière identique à travers les navigateurs et applique les transformations spec-définies décrites ci-dessus est sûr.

Ce que cet outil fait (et ne fait pas)

Cet outil est un minifieur en navigateur en un seul fichier, environ 30 lignes de JavaScript. Il tokenise les littéraux de chaîne dans des placeholders pour que les passes suivantes ne puissent pas corrompre leur contenu, supprime les commentaires /* ... */, réduit l’espace blanc autour de {, }, :, ;, ,, >, ~, +, supprime le point-virgule final avant }, réduit les suites d’espaces blancs à un seul espace, raccourcit les couleurs hex à six chiffres en trois chiffres lorsque chaque paire de chiffres est identique, et retire l’unité des valeurs zéro pour px, em, rem, %, pt, ex, ch, vw, vh, vmin, vmax. Il n’analyse pas le CSS en un AST, c’est une passe regex. Il ne réduit pas longhand en shorthand. Il ne fusionne ni ne dédoublonne les sélecteurs. Il ne réordonne pas les déclarations. Il ne convertit pas rgb() en hex ni les couleurs nommées en hex. Il ne met pas les mots-clés en minuscules. Il ne préserve pas les commentaires « importants » /*!: tous les commentaires sont strippés à l’identique ; si vous avez des en-têtes de licence à conserver, recollez-les après la minification. Il n’émet pas de source map. Le cadrage honnête : collez le CSS qui est sorti de votre éditeur ou de votre main, récupérez une version dépouillée typiquement 20-40 % plus petite en octets bruts, et utilisez-la comme artefact de déploiement rapide pour des sites construits à la main. Pour des projets avec un pipeline de build, utilisez cssnano ou Lightning CSS dans ce pipeline ; pour ceux qui n’en ont pas, cet outil retire la friction.

Pourquoi le tout-navigateur compte ici

Tout minifieur CSS web a le même choix d’architecture : faire le travail sur un serveur, ou le faire dans le navigateur de l’utilisateur. Le traitement côté serveur exige de téléverser la feuille de style sur le réseau, ce qui veut dire qu’une copie de ce CSS reste dans les logs du serveur, peut-être dans un cache CDN, peut-être dans un pipeline d’analytique, peut-être dans une sauvegarde. Pour la plupart du CSS, c’est inoffensif. Pour des outils internes, des styles de produits non publiés ou des feuilles contenant des sélecteurs révélant les taxonomies internes de classes (.admin-panel-internal-debug-info), non. Même pour du CSS de site marketing ordinaire, un développeur auditant ce qu’il envoie réellement sur le réseau peut raisonnablement préférer que le travail en cours reste sur sa machine. Un minifieur purement basé navigateur (du JavaScript qui tourne dans votre onglet et ne fait jamais de requête réseau après le chargement initial de la page) contourne le problème. Vous pouvez le vérifier : ouvrez l’onglet Réseau des DevTools, collez le CSS, cliquez sur Minifier, et guettez n’importe quelle requête sortante. Il n’y en aura aucune. Mieux encore, déconnectez-vous d’internet (ou activez le mode avion) après le chargement de la page et l’outil fonctionnera quand même, ce qui est la preuve empirique la plus forte que rien n’est téléversé.

Questions fréquentes

De combien mon CSS va-t-il rétrécir ?

Un CSS formaté à la main avec commentaires et indentation rétrécit typiquement de 20 à 40 % en octets bruts. Un CSS qui a déjà été compilé depuis Sass/Less et légèrement formaté rétrécit moins. Un CSS qui a été traité par PostCSS ou Autoprefixer a souvent déjà des commentaires minimaux et rétrécit le moins. La taille après compression Brotli en périphérie de CDN se resserrera encore, Brotli sur du CSS minifié économise toujours 5-15 % de plus que Brotli sur du CSS non minifié, selon le degré de répétitivité de l’espace blanc d’origine.

La sortie minifiée va-t-elle casser quelque chose ?

Pour du CSS ordinaire, non, les transformations sont sûres selon la spec. Les deux cas qui valent la peine d’être vérifiés vous-même : (1) les valeurs zéro à l’intérieur de calc(), min(), max(), clamp() et des propriétés CSS personnalisées ne devraient pas être unit-strippées parce que les règles d’arithmétique typée exigent une unité ; la passe regex de cet outil est conservatrice mais si vous avez calc(0px + 10%) dans votre CSS, regardez la sortie. (2) Si votre feuille de style a des fallbacks de propriétés dupliquées comme display: flex; display: grid;, cet outil préserve les deux, mais des minifieurs avancés comme cssnano avec le preset advanced supprimeraient le premier. Si vous dépendez d’un comportement de cascade spécifique à un navigateur, auditez avant de déployer.

Préserve-t-il les en-têtes de licence ?

Non. Les minifieurs de production respectent la convention selon laquelle les commentaires commençant par /*! (avec un point d’exclamation) sont préservés comme « importants », habituellement pour les en-têtes de copyright et les notices de licence. Cet outil retire tous les commentaires de la même manière. Si vous livrez du CSS qui a besoin d’un en-tête de licence (MIT, GPL, attribution source BSD), recollez l’en-tête manuellement dans la sortie. Pour un pipeline qui a besoin de préservation automatique, utilisez cssnano ou Lightning CSS à la place.

Devrais-je l’utiliser si j’ai déjà un pipeline de build ?

Probablement pas, votre bundler le fait pour vous. webpack 5 livre css-minimizer-webpack-plugin avec cssnano sous le capot ; Vite utilise esbuild pour la minification CSS par défaut ; Parcel utilise Lightning CSS. Cet outil est pour les cas que votre pipeline de build ne couvre pas : HTML écrit à la main, thèmes WordPress livrés sans toolchain Node, générateurs de sites statiques qui ne bundlent pas la minification, fichiers CSS ponctuels pour un modèle d’e-mail ou une démo rapide. Pour ceux-là, un outil paste-in dans le navigateur est le chemin de moindre résistance.

Mes fichiers sont-ils téléversés ?

Non. Le minifieur est du JavaScript qui tourne dans votre navigateur. Le CSS que vous collez ne traverse jamais le réseau, vérifiez dans l’onglet Réseau des DevTools pendant que vous cliquez sur Minifier, ou mettez la page hors ligne après son chargement et confirmez que l’outil fonctionne toujours. Les feuilles de style internes, les styles de produits non publiés et le CSS révélant les taxonomies internes de classes restent sur votre appareil.

Puis-je dé-minifier la sortie plus tard ?

Pas exactement, les commentaires et l’espace blanc d’origine sont partis pour de bon, c’est le but. Mais vous pouvez formater le CSS minifié pour le rendre lisible à nouveau. Des pretty-printers comme Prettier (avec le plugin CSS), la commande Format Document intégrée dans VS Code, ou n’importe lequel des outils en ligne « beautifier CSS » réinséreront indentation et sauts de ligne. Ils ne peuvent pas récupérer les commentaires supprimés. Gardez toujours votre source non minifiée dans le contrôle de version comme forme canonique.

Outils associés