Marre de Bootstrap ? Tailwind CSS à la rescousse !

Thomas Fortin
30/01/2020

Marre de Bootstrap ? Tailwind CSS à la rescousse !

Préambule

Logo et description officiels de Tailwind CSS Logo et description officiels de Tailwind CSS (Source: tailwindcss.com)

Mettre en place tout un site à son image (ou à celle de son graphiste…) peut être un processus très long et complexe. De plus, l’ajout de classes à tout va avec un grand nombre de répétitions de classes et propriétés similaires peut très vite alourdir le code de l’application.
C’est pour palier à ces problèmes récurrents que Twitter sort la première version stable de son framework CSS en 2011 : Bootstrap. Avant cela il fallait, soit tout écrire soi-même, soit avoir plusieurs bibliothèques plus ou moins spécialisées, ce qui amenait à une maintenabilité réduite.
Suite au succès de Bootstrap, beaucoup de nouvelles bibliothèques ont vu le jour, telles que Material Design de Google, Semantic UI, Foundation, et un tas d’autres…

Dans cet article, nous allons nous intéresser à un de ces frameworks sorti très récemment : Tailwind CSS (nous parlons bien ici de framework CSS, et non de UI Kit).

Présentation du framework

Tailwind CSS est un framework CSS très récent (du moins au moment où j’écris cet article…) qui a vu sa première version stable sortir en mai 2019, suite à 1 an et demi de développement après sa toute première version alpha de novembre 2017. Un récapitulatif des “Release Notes” est disponible à cette page.

Optimisation

Intéressons-nous à un détail important qui peut faire toute la différence lors du choix du framework : la taille.

Taille de différents frameworks CSS lors de leur import dans un projet Taille de différents frameworks CSS lors de leur import dans un projet (Source: tailwindcss.com)

En regardant le tableau comparatif ci-dessus, on peut (légitimement) se poser la question : Pourquoi utiliser Tailwind, s’il est l’un des frameworks CSS les plus lourds actuellement ?
Une des fonctionnalités qui fait la force de Tailwind, c’est qu’il est hautement configurable, ce qui permet de n’utiliser que ce dont on a besoin dans le projet, et par conséquent réduire sa taille.

Pour faire cela, il est possible de retirer certaines valeurs du thème qui sont inutilisées.

Avant de poursuivre, je précise que nous verrons des exemples de configuration dans la suite de l’article et donc comment mettre en place les changements que je vais évoquer dans cette section.

La première manipulation, et sûrement la plus importante, est que l’on peut réduire le nombre de couleurs disponibles dans la palette de base. En effet, de base Tailwind propose une très large palette composée de 93 couleurs (ayant chacune des classes pour les backgrounds, les borders et les textes, ayant elles-mêmes chacune des variantes :hover et :focus) !
Pour donner un ordre d’idée, cela correspond à la génération de 4185 classes sur les 8271 classes disponibles au total dans le build par défaut.

Évolution de la taille de Tailwind selon la taille de la palette de couleurs Évolution de la taille de Tailwind selon la taille de la palette de couleurs (Source: tailwindcss.com)

Dans un cas réel, il est très rare d’avoir besoin d’une palette avec 93 couleurs. On remarque qu’en descendant à 25 couleurs (ce qui n’est déjà pas mal du tout), on réduit déjà beaucoup la taille de notre import Tailwind. Rien qu’en modifiant cette configuration, nous pouvons descendre à 12.2kb seulement avec Brotli, ce qui est déjà moins que toutes les autres librairies CSS (à l’exception de Tachyons, qui est une librairie moins complète…).

Le second exemple donné sur le site de Tailwind est sur la réduction du nombre de breakpoints qui est par défaut de 4.

Évolution de la taille de Tailwind selon le nombre de breakpoints Évolution de la taille de Tailwind selon le nombre de breakpoints (Source: tailwindcss.com)

Désormais, avec des écrans de smartphone de plus en plus grands, la nécessité d’avoir 4 breakpoints se pose de plus en plus… Par défaut, les breakpoints suivants sont disponibles : 640px, 768px, 1024px et 1200px.
Même si le passage à seulement 1 même 2 breakpoints semble compliqué pour certains sites ou applications complètement responsive, n’en avoir que 3 semble tout de même suffisant dans tous les cas.

On peut voir ici que, même si la réduction est minime par rapport à la réduction du nombre de couleurs, elle reste non négligeable… Il faut surtout imaginer les deux réductions combinées ! Le passage de 93 couleurs à par exemple 15 couleurs, et de 4 breakpoints a seulement 3, réduit considérablement la taille de notre import Tailwind !

Les tableaux comparatifs et leurs explications sont disponibles sur cette page.

Personnalisation

En plus de l’optimisation poussée qu’il est possible d’en faire, le framework permet une personnalisation très avancée.

Voyons un exemple de personnalisation.

Imaginons que nous ayons une application qui nécessite seulement les éléments suivants :

  • Couleurs : noir, gris, blanc qui font partie du package de base, puis vert et bleu ainsi que leurs dégradés (que nous définirons précisément) que nous personnaliserons ;

  • Breakpoints : 3 breakpoints seulement (md, lg & xl) ;

  • Spacing : ajout de quelques spacing, en plus de ceux déjà existants de base ;

  • Autres : nous savons que nous n’utiliserons par exemple pas les propriétés : float, visibility, ou encore les object-position.

Dans un projet plus important, il y aura évidemment bien plus de configuration, mais cette configuration simple permet simplement de montrer la façon de faire et sa simplicité.

Voici le fichier de configuration tailwind.config.js que cela nous donne :

// Import colors of default TailwindCSS theme
const { colors } = require('tailwindcss/defaultTheme');

module.exports = {
  theme: {
    // Manage breakpoints
    screens: {
      'md': '768px',
      'lg': '1024px',
      'xl': '1280px'
    },
    colors: {
      black: colors.black,
      white: colors.white,
      gray: colors.gray,
      // Add our custom "blue" and "green" colors
      blue: {
        '300': '#00b7ff',
        '400': '#04Aef0',
        '500': '#08a5e1',
        '600': '#0795d3',
        '700': '#0586c5'
      },
      green: {
        '300': '#25e471',
        '400': '#29d970',
        '500': '#2dcf6e',
        '600': '#30c46c',
        '700': '#33ba6a'
      }
    },
    // Extend default spacing with 72, 84 and 96 values
    extend: {
      spacing: {
        '72': '18rem',
        '84': '21rem',
        '96': '24rem'
      }
    }
  },
  variants: {},
  // Remove useless default utilities
  corePlugins: {
    float: false,
    visibility: false,
    objectPosition: false
  },
  plugins: []
};

Exemple de fichier de configuration simple de Tailwind CSS

Explications :

  • Personnalisation des couleurs : vous pouvez aller de 100 à 900, mais ce n’est pas obligatoire si ce n’est pas nécessaire, la 500 étant la couleur “de base”. Exemple d’utilisation dans le CSS : theme('colors.blue.500') pour utiliser notre couleur personnalisée bleue avec le dégradé 500 ;

  • Gestion des breakpoints : ici, nous disons que nous ne voulons utiliser que 3 breakpoints au lieu de 4 par défaut. Tout en sachant que les noms de ceux-ci peuvent être changés comme on le souhaite ;

  • Ajout de spacing : l’ajout de ces spacing permet la génération de classe pour les padding,margin et height du type : .p-72, .m-72 et .h-72 pour chacun des ajouts ;

  • Suppressions d’utilitaires : en mettant à false ces quelques utilitaires, nous disons que nous n’avons pas besoin des classes associées, et nous évitons donc de les importer afin de gagner en taille d’import. Par exemple avec la configuration ci-dessus, nous n’aurons plus accès aux classes comme .float-right, .invisible, .object-left-bottom, entre autres…

Il faut avoir en tête que toutes les propriétés disponibles dans Tailwind sont personnalisables de cette façon ! Ce qui rend le framework très flexible.

Vous pouvez trouver un exemple de configuration très complet sur le GitHub de l’application Firefox Send faite avec Tailwind, en suivant ce lien.

Voyons maintenant comment ajouter Tailwind CSS dans son projet…

Ajout de Tailwind CSS dans un projet

Voici les méthodes pour intégrer simplement Tailwind CSS à son projet selon la technologie utilisée :

Vue.js

Logo Vue.js Logo Vue.js (Source: vuejs.org)

Afin d’intégrer Tailwind CSS à son projet Vue.js, c’est très simple, une fois le projet créé, voici les étapes à suivre :

  1. Ajout du package au projet

// using NPM npm install tailwindcss --save-dev
// OR using Yarn yarn add tailwindcss --dev

2. Création du fichier de configuration

La commande ci-dessous va générer un fichier de configuration pré-construit à la racine du projet (à lancer depuis la racine).

// using npx npx tailwind init
// OR without npx./node_modules/.bin/tailwind init tailwind.config.js

3. Configuration de PostCSS (facultatif)

L’étape suivante permet de configurer PostCSS. Ce n’est pas obligatoire, mais tellement utile et pratique : je vous conseille vraiment de le faire !
PostCSS est un outil qui permet d’automatiser certaines tâches rébarbatives du CSS. Par exemple, l’Autoprefixer va automatiquement ajouter les préfixes CSS -webkit-, -moz-, etc… lorsque ceux-ci sont nécessaires Vous n’aurez donc plus à vous soucier des compatibilités navigateurs de certaines propriétés.
La liste des fonctionnalités est visible sur leur site. Pour cela, il suffit d’entrer la configuration suivante dans le fichier postcss.config.js (si le fichier n’existe pas, créez le simplement avec la commande touch postcss.config.js lancée à la racine du projet) :

module.exports = {
    "plugins": [
        require('tailwindcss')('tailwind.js'),
        require('autoprefixer')()
    ]
}

Exemple de fichier de configuration simple de PostCSS avec Tailwind CSS

Si dans la configuration initiale de votre projet vous aviez mis la configuration de PostCSS à l’intérieur du fichier package.json, supprimez le bloc postcss.

4. Import des fichiers de Tailwind CSS

La dernière étape va être d’importer automatiquement les fichiers de Tailwind CSS pour avoir accès à toutes ses classes, depuis n’importe quel composant. Pour cela, il faudra créer un fichier SCSS que vous pouvez mettre à l’emplacement suivant : src/assets/scss/tailwind.scss et dont voici le contenu (selon les éléments que vous souhaitez utiliser dans votre projet) :

@tailwind base;
@tailwind components;
@tailwind utilities;

Exemple de fichier d’import des fichiers de base de Tailwind CSS

La règle @tailwind ne sera très probablement pas reconnue par votre éditeur de texte, mais pas de panique, la commande est correcte !

Une fois que ce fichier est prêt, il ne nous reste plus qu’à dire à notre application de le charger par défaut, en ajoutant tout simplement la ligne suivante au début de notre fichier main.js :

import '@/assets/scss/tailwind.scss';

Une autre façon de faire si vous avez un fichier SCSS global (ce qui est très souvent le cas) est de faire l’import précédent dans ce même fichier SCSS global, et n’avoir que l’import de ce fichier global dans votre fichier main.js.

Après toutes ces étapes, place aux tests ! Utilisez les classes de Tailwind CSS dans vos composants pour vérifier qu’elles sont bien reconnues et prises en compte !

Nuxt.js

Logo Nuxt.js Logo Nuxt.js (Source: nuxtjs.org)

Pour Nuxt.js, il y a 2 possibilités :

  1. Vous êtes sur un projet existant. Dans ce cas, la procédure est la même que pour Vue.js ;

  2. Vous voulez partir sur un nouveau projet. Dans ce cas, rien de plus simple pour intégrer Tailwind CSS, puisque son intégration est directement proposée par défaut dans la CLI(*) :

// using npx$ npx create-nuxt-app <project-name>
// OR using yarn$ yarn create nuxt-app <project-name>

Ensuite, après quelques questions, la CLI demande quel framework UI vous voulez installer. Ici, Tailwind CSS est directement proposé, comme le montre la capture d’écran ci-dessous :

Exemple de création d’application Nuxt.js via sa CLI

Une fois que cela est fait, aucune configuration n’est nécessaire, tout est fait pour vous 🙂

(*) : Si vous n’avez pas yarn, la CLI de Nuxt.js nécessite d’avoir npx, qui est installé par défaut avec npm à partir de sa version 5.2.0.

Je n’ai donné les exemples d’intégration que pour des applications Vue.js et Nuxt.js car ce sont les 2 frameworks auxquels je m’intéresse particulièrement en ce moment, mais il est évidemment possible de l’intégrer à des applications Angular, React, etc… Des tutoriels plutôt bien faits sont disponibles en ligne… Je ne vais pas détailler l’intégration à chaque framework puisque ce serait trop long, trop répétitif (la manipulation est sensiblement la même pour les différents frameworks), et ce n’est pas le but de cet article…

En pratique : comparaison Bootstrap/Tailwind

Afin de voir Tailwind dans la pratique, je vais construire un exemple d’IHM simple réalisé avec Bootstrap (qui est le framework CSS le plus connu et utilisé), puis montrer l’équivalent Tailwind de cette portion de code.

Exemple de snippet à réaliser avec Bootstrap puis Tailwind Résultat que l’on souhaite obtenir (en étant responsive !)

Avec Bootstrap :

<div class="d-flex flex-wrap p-2">
    <div class="px-1 mb-2 col-12 col-sm-6 col-md-4 col-lg-3">
        <div class="border rounded h-100 px-3 py-4">
            <div class="d-flex flex-column flex-grow-1 flex-shrink-1 h-100">
                <h2 class="mb-2 text-center font-weight-light">Card 1 title</h2>
                <p class="text-center"><small class="text-muted">Card 1 sub-title</small></p>
                <p class="flex-grow-1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin aliquam purus ullamcorper dignissim fermentum. Cras hendrerit tristique vehicula.</p>
                <a href="#" class="btn btn-primary">Link to details</a>
            </div>
        </div>
    </div>
    <!-- Other cards... -->
</div>

Structure du code précédent réalisé avec Bootstrap.

Avec Tailwind :

<div class="flex flex-wrap p-2">
    <div class="px-1 mb-2 w-full sm:w-1/2 md:w-1/3 lg:w-1/4">
        <div class="border rounded h-full px-3 py-4">
            <div class="flex flex-col flex-grow flex-shrink h-full">
                <h2 class="mb-1 text-center text-3xl font-light">Card 1 title</h2>
                <p class="text-center mb-3"><small class="text-gray-700">Card 1 sub-title</small></p>
                <p class="flex-grow mb-2">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin aliquam purus ullamcorper dignissim fermentum. Cras hendrerit tristique vehicula.</p>
                <a href="#" class="border border-blue-600 rounded py-2 mt-3 text-center cursor-pointer bg-blue-600 text-white">Link to details</a>
            </div>
        </div>
    </div>
    <!-- Other cards... -->
</div>

Structure du code précédent réalisé avec Tailwind.

On remarque que les deux codes sont assez similaires, les seules différences se font dans la syntaxe des noms de classes.

À noter que si quelques légères différences apparaissent entre les deux résultats, cela se joue tout simplement dans la configuration de Bootstrap et/ou Tailwind comme vu précédemment, notamment sur les couleurs du thème, ou la taille du padding pour les classes spécifique dans Tailwind.

Le plus de Tailwind

Il y a une chose que Tailwind permet et que Bootstrap ne permet pas (ou du moins pas encore, au moment d’écrire ces lignes), c’est ce qui est appelé les Pseudo-Class Variants dans Tailwind.

En effet, il est possible de gérer l’ajout de classes lorsqu’un élément est dans un état différent, par exemple : hover, focus, etc…

Reprenons l’exemple précédent, en y ajoutant un petit quelque chose. Imaginons que sur les liens, nous voulions qu’au survol, les couleurs du texte et du fond soient inversées. C’est-à-dire passer d’un fond bleu avec texte blanc, à un fond blanc avec texte bleu.

Avec Bootstrap, il nous faudrait créer du CSS personnalisé afin d’effectuer ce changement et inverser l’application des couleurs au moment du hover. Si l’on suppose que l’on ajoute une classe nommée custom-btn-blue à ces boutons, afin de faciliter l’exemple, il faudrait faire :

.custom-btn-blue:hover {
    color: $primary;
    background-color: white;
}

Avec Tailwind, les Pseudo-Class Variants nous permettent de faire cela très simplement, sans avoir à créer de CSS personnalisé, de la manière suivante :

<a class="border border-blue-600 rounded py-2 mt-3 text-center cursor-pointer bg-blue-600 text-white hover:bg-white hover:text-blue-600">Link to details</a>

Cela permet également de ne cibler que certains éléments accessibles via les pseudo-sélecteurs, par exemple si l’on veut un border-top sur chaque élément d’une liste, sauf le premier :

<div class="border rounded">
    <div v-for="item in items" class="border-t first:border-t-0">
        {{ item }}
    </div>
</div>


Conclusion

Tailwind est un framework CSS très récent qui promet de grandes choses. Sa grande flexibilité et sa configuration poussée permet de s’ajuster au plus près de nos besoins, sans avoir à faire d’imports de classes inutiles.
Au-delà de ça, la doc extrêmement claire et bien faite du framework est un énorme plus… Dans cette doc, on peut même y trouver une solution pour supprimer la moindre classe du framework inutilisée en plus de la configuration, grâce à un mini-tuto sur l’installation et la configuration de PurgeCSS ! Parfait si vous ne voulez pas vous perdre dans une configuration trop précise…

Bonus 1 : Si vous voulez voir Tailwind en action, quelques “gros sites” ont déjà adopté le framework, comme Firefox Send (dont le code source se trouve sur ce repo GitHub, si vous voulez plus de détails, dont la configuration du framework dans le projet) ou encore Laracasts.

Bonus 2 : Si vous utilisez VSCode, un plugin très bien fait est là pour vous aider, Tailwind CSS IntelliSense. Le plugin vous permet de vous aider à retrouver les classes dont vous avez besoin grâce à de l’auto-complétion lorsque vous ajoutez des classes CSS à vos balises HTML. Et si vous n’utilisez pas VSCode… Faites-le ! 😀

Si vous avez apprécié cet article ou qu’il vous a été utile, n’hésitez pas à le partager ! 🙂