Aller au contenu

Tailwind CSS : organisation et composants

La répétition de classes se résout par un composant (Astro, React…) plutôt que par une classe CSS personnalisée.

Composant Astro src/components/Bouton.astro :

---
interface Props {
href?: string;
variante?: 'primaire' | 'secondaire';
}
const { href, variante = 'primaire', class: classe } = Astro.props;
const Balise = href ? 'a' : 'button';
const styles = {
primaire: 'bg-blue-600 text-white hover:bg-blue-700',
secondaire: 'border border-slate-300 bg-white hover:bg-slate-50',
};
---
<Balise
href={href}
class:list={[
'inline-flex items-center rounded-lg px-4 py-2 text-sm font-medium transition-colors',
'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600',
styles[variante],
classe,
]}
>
<slot />
</Balise>

Composant React :

export function Bouton({ variante = 'primaire', className = '', ...props }) {
const styles = {
primaire: 'bg-blue-600 text-white hover:bg-blue-700',
secondaire: 'border border-slate-300 bg-white hover:bg-slate-50',
};
return (
<button
className={`inline-flex rounded-lg px-4 py-2 text-sm font-medium ${styles[variante]} ${className}`}
{...props}
/>
);
}
Fenêtre de terminal
npm install clsx tailwind-merge
src/lib/cn.js
import { clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
export const cn = (...entrees) => twMerge(clsx(entrees));
<div
className={cn('p-2 text-sm', actif && 'bg-blue-600 text-white', className)}
/>

twMerge résout les conflits : cn('p-2', 'p-4') produit p-4 (une classe passée par l’appelant remplace celle par défaut).

Fenêtre de terminal
npm install class-variance-authority
import { cva } from 'class-variance-authority';
export const bouton = cva('inline-flex items-center rounded-lg font-medium', {
variants: {
variante: {
primaire: 'bg-blue-600 text-white hover:bg-blue-700',
secondaire: 'border border-slate-300 bg-white hover:bg-slate-50',
},
taille: { sm: 'px-3 py-1 text-sm', md: 'px-4 py-2' },
},
defaultVariants: { variante: 'primaire', taille: 'md' },
});
bouton({ variante: 'secondaire', taille: 'sm' });

Les classes d’un contenu Markdown ne sont pas modifiables : le plugin officiel Typography les stylise.

Fenêtre de terminal
npm install @tailwindcss/typography
@import 'tailwindcss';
@plugin '@tailwindcss/typography';
<article class="prose prose-slate dark:prose-invert max-w-none">
<!-- HTML issu du Markdown -->
</article>

Le plugin @tailwindcss/forms donne une base cohérente aux champs :

Fenêtre de terminal
npm install @tailwindcss/forms
@plugin '@tailwindcss/forms';
  • Trier avec prettier-plugin-tailwindcss (voir Installation).
  • Retours à la ligne par groupe (mise en page, espacements, couleurs, états).
  • Extraire dès qu’un motif apparaît 3 fois ou plus.
  • Préférer les valeurs du thème aux valeurs arbitraires.
  • Éviter les conditions complexes dans l’attribut class : les placer dans une fonction.
<button
class="rounded-lg bg-blue-600 px-4 py-2 text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
>
Valider
</button>
<span class="sr-only">Texte pour lecteurs d'écran</span>
  • Toujours prévoir un état de focus visible.
  • Vérifier les contrastes (texte clair sur fond clair est un défaut fréquent avec text-slate-400).
  • Zones cliquables d’au moins 48 px (min-h-12 min-w-12) sur mobile.
  • Respecter motion-reduce: pour les animations.
  • Le CSS généré est proportionnel aux classes utilisées : pas d’inquiétude sur le nombre de classes.
  • Éviter les classes dynamiques non détectables.
  • Construire en production avec minification (--minify de la CLI, ou le build du framework).
  • Charger le CSS une seule fois (un fichier global).
Symptôme Piste
Une classe passée à un composant n’a pas d’effet Conflit avec une classe par défaut : twMerge
@plugin ignoré Paquet non installé, ou directive placée avant @import "tailwindcss"
Le Markdown n’est pas stylé Classe prose absente, plugin Typography non chargé
prose impose une largeur maximale max-w-none
Classe construite dynamiquement non appliquée Noms de classes complets dans le code source
Les classes d’une bibliothèque tierce sont absentes @source vers ses fichiers

Ubuntu 24.04 et 26.04 : différences à connaître

Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »

Aucune.