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