Retour au blog

CSS-in-JS en 2025 : Tailwind Domine Tandis Que Styled-Components Perd du Terrain

Salut HaWkers, la guerre des styles en JavaScript a eu un gagnant clair en 2025 : Tailwind CSS domine avec 68% d'adoption, tandis que les solutions CSS-in-JS traditionnelles comme Styled-Components perdent du terrain.

Pourquoi ce changement radical ? Et qu'est-ce que ça signifie pour comment vous devriez styliser vos composants ?

L'Ascension de Tailwind CSS

// Avant : Styled-Components (2020-2022)
import styled from 'styled-components';

const Button = styled.button`
  background-color: ${props => props.primary ? '#007bff' : '#6c757d'};
  color: white;
  padding: 0.5rem 1rem;
  border-radius: 0.25rem;
  border: none;
  font-size: 1rem;
  cursor: pointer;
  transition: all 0.2s;

  &:hover {
    background-color: ${props => props.primary ? '#0056b3' : '#545b62'};
    transform: translateY(-1px);
  }

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
`;

function MyComponent() {
  return (
    <Button primary onClick={handleClick}>
      Cliquez-moi
    </Button>
  );
}

// Maintenant : Tailwind CSS (2025)
function MyComponent() {
  return (
    <button
      className="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded
                 transition-all hover:-translate-y-px disabled:opacity-50
                 disabled:cursor-not-allowed"
      onClick={handleClick}
    >
      Cliquez-moi
    </button>
  );
}

// Moins de code, sans runtime overhead, même résultat !

Pourquoi Tailwind a gagné :

  • Zero runtime : Les classes sont compilées au build time
  • Bundle size plus petit : Seul le CSS utilisé est inclus
  • Vitesse de développement : Pas besoin de penser aux noms de classes
  • Consistance : Design system intégré
  • Performance : Aucun JS supplémentaire en runtime
  • Autocomplete : Excellente DX avec intégration IDE

Le Déclin du CSS-in-JS Runtime

Styled-Components, Emotion et similaires font face à des problèmes en 2025 :

Problème 1 : Runtime Performance

// Styled-Components - Overhead en runtime
import styled from 'styled-components';

const Card = styled.div`
  padding: ${props => props.size === 'large' ? '2rem' : '1rem'};
  background: ${props => props.theme.background};
  border-radius: 8px;
`;

// À chaque render :
// 1. Parse le template string
// 2. Génère du CSS dynamique
// 3. Injecte dans le DOM
// 4. Met à jour les classes

// Ça se passe en RUNTIME = Impact sur la performance !

Problème 2 : Server Components

// React Server Components (Next.js 15+)
// ❌ Styled-Components NE fonctionne PAS dans les Server Components !
'use server'; // Erreur !

import styled from 'styled-components';

const Title = styled.h1`
  color: blue;
`;

// ✅ Tailwind fonctionne parfaitement
'use server';

export default function ServerComponent() {
  return (
    <h1 className="text-blue-600 text-3xl font-bold">
      Hello from Server Component
    </h1>
  );
}

La Nouvelle Génération : Zero-Runtime CSS-in-JS

// Vanilla Extract - CSS-in-JS sans runtime
// styles.css.ts
import { style } from '@vanilla-extract/css';

export const button = style({
  backgroundColor: '#007bff',
  color: 'white',
  padding: '0.5rem 1rem',
  borderRadius: '0.25rem',
  border: 'none',
  cursor: 'pointer',
  ':hover': {
    backgroundColor: '#0056b3'
  }
});

// Component.tsx
import { button } from './styles.css';

export function Button() {
  return (
    <button className={button}>
      Cliquez-moi
    </button>
  );
}

// CSS généré au BUILD TIME, zéro runtime !

Tailwind + Composants : Le Pattern Actuel

// components/Button.tsx - Pattern recommandé 2025
import { cva, type VariantProps } from 'class-variance-authority';

const buttonVariants = cva(
  // Styles de base
  'inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50',
  {
    variants: {
      variant: {
        primary: 'bg-blue-600 text-white hover:bg-blue-700',
        secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300',
        outline: 'border border-gray-300 bg-transparent hover:bg-gray-100',
        ghost: 'hover:bg-gray-100'
      },
      size: {
        sm: 'h-9 px-3 text-sm',
        md: 'h-10 px-4 py-2',
        lg: 'h-11 px-8 text-lg'
      }
    },
    defaultVariants: {
      variant: 'primary',
      size: 'md'
    }
  }
);

interface ButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof buttonVariants> {}

export function Button({ variant, size, className, ...props }: ButtonProps) {
  return (
    <button
      className={buttonVariants({ variant, size, className })}
      {...props}
    />
  );
}

// Usage :
<Button variant="primary" size="lg">
  Cliquez-moi
</Button>

<Button variant="outline" size="sm">
  Petit bouton
</Button>

CSS Modules : L'Option Sous-estimée

/* Button.module.css */
.button {
  padding: 0.5rem 1rem;
  border-radius: 0.25rem;
  border: none;
  cursor: pointer;
  transition: all 0.2s;
}

.primary {
  background-color: #007bff;
  color: white;
}

.primary:hover {
  background-color: #0056b3;
}

.secondary {
  background-color: #6c757d;
  color: white;
}
// Button.tsx
import styles from './Button.module.css';

interface ButtonProps {
  variant?: 'primary' | 'secondary';
  children: React.ReactNode;
}

export function Button({ variant = 'primary', children }: ButtonProps) {
  return (
    <button className={`${styles.button} ${styles[variant]}`}>
      {children}
    </button>
  );
}

// Zero runtime, type-safe, scoped styles !

Comparaison : Tailwind vs CSS-in-JS vs CSS Modules

Feature Tailwind Styled-Comp Vanilla Extract CSS Modules
Runtime Zero Oui Zero Zero
Bundle Size ~10KB ~15KB ~8KB 0KB
DX Excellent Très bien Bien Moyen
Performance Excellente Mauvaise Excellente Excellente
TypeScript Partiel Bien Excellent Moyen
Server Comp
Learning Curve Moyenne Facile Moyenne Facile

Quand Utiliser Chaque Approche

Utilisez Tailwind quand :

✅ Vous voulez une vitesse de développement maximale
✅ Design system consistant
✅ Zero runtime est la priorité
✅ Server Components
✅ Nouveaux projets en 2025

Utilisez CSS Modules quand :

✅ Vous préférez le CSS traditionnel
✅ Migration de projet legacy
✅ Équipe expérimentée en CSS
✅ Vous voulez zéro overhead même dans le bundle

Utilisez CSS-in-JS Zero-Runtime quand :

✅ Vous avez besoin de type-safety complet
✅ Styles complexes et dynamiques
✅ Vous voulez le meilleur du CSS et TypeScript
✅ Performance critique

Évitez CSS-in-JS Runtime quand :

⚠️ Les Server Components sont nécessaires
⚠️ La performance est critique
⚠️ Le bundle size importe
⚠️ Vous démarrez un nouveau projet

Le Futur : Native CSS Nesting et Layers

/* CSS moderne (supporté en 2025) */
.card {
  padding: 1rem;
  border-radius: 8px;

  /* Nesting natif ! */
  .title {
    font-size: 1.5rem;
    font-weight: bold;
  }

  .description {
    color: gray;
  }

  /* Pseudo-classes */
  &:hover {
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  }

  /* Media queries imbriquées */
  @media (min-width: 768px) {
    padding: 2rem;
  }
}

/* CSS Layers pour contrôle de spécificité */
@layer base, components, utilities;

@layer base {
  h1 { font-size: 2rem; }
}

@layer components {
  .btn { padding: 0.5rem 1rem; }
}

@layer utilities {
  .text-center { text-align: center; }
}

Statistiques 2025 :

  • 68% des nouveaux projets utilisent Tailwind
  • 15% utilisent CSS Modules
  • 10% utilisent CSS-in-JS zero-runtime
  • 7% utilisent encore Styled-Components/Emotion

Si vous voulez en savoir plus sur les tendances modernes de front-end, consultez : Svelte 5 Runes : La Révolution de Réactivité où nous explorons comment les frameworks modernes changent non seulement le state, mais aussi le styling.

C'est parti ! 🦅

📚 Vous Voulez Approfondir Vos Connaissances en JavaScript ?

Cet article a couvert le styling moderne, mais il y a beaucoup plus à explorer dans le monde du développement moderne.

Options d'investissement :

  • €9,90 (paiement unique)

👉 Découvrir le Guide JavaScript

💡 Matériel mis à jour avec les meilleures pratiques du marché

Commentaires (0)

Cet article n'a pas encore de commentaires. Soyez le premier!

Ajouter des commentaires