Créer un footer React sombre et minimaliste
Un footer React sombre minimaliste centre le nom de marque, les liens de nav, les liens sociaux et le copyright dans une colonne verticale unique via flexbox et des propriétés CSS personnalisées pour le thème. Aucune bibliothèque externe ; les états hover sont gérés avec des handlers onMouseEnter/onMouseLeave inline.
- Stack : React (composant client), propriétés CSS personnalisées, zéro dépendance externe, ~130 lignes.
- Animation : CSS uniquement, transition couleur sur les liens à 0.15s, pas de Framer Motion.
- Layout : colonne flexbox centrée unique ; chaque section est optionnelle et ne s'affiche que si des données sont fournies.
- Accessible : balises anchor natives, élément footer sémantique, contraste texte à 40-50% blanc sur fond sombre.
- Responsive par défaut ; flexWrap sur la ligne de navigation gère les viewports étroits.
Footer Dark Minimal est un footer React centré, empilé en colonne, pour les sites à thème sombre. Il affiche un nom de marque en lien majuscule, un tagline optionnel, une rangée de navigation avec retour à la ligne, une rangée de liens sociaux et une ligne de copyright, le tout séparé par un séparateur de 40px. Chaque section s'affiche conditionnellement, donc tu n'intègres que ce dont tu as besoin.
Anatomie
Un élément `<footer>` enveloppe un div conteneur centré (max-width depuis `--container-max-width`, padding depuis `--container-padding-x`). À l'intérieur, cinq enfants empilés : un `<a>` pour le nom de marque (majuscule, poids 700), un `<p>` optionnel pour la description, un `<nav>` en rangée flex avec retour à la ligne pour les liens de page, une rangée flex pour les liens sociaux, une règle horizontale de 40px sous forme de `<div>` (hauteur 1px, `--color-border-dark`), et un `<p>` pour la ligne de copyright. L'écart entre les rangées est de 1.5rem.
Comment ça marche
Le composant est une fonction React purement présentationnelle sans state ni effet. Le thème repose entièrement sur des propriétés CSS personnalisées (`--color-background-dark`, `--color-foreground-on-dark`, `--color-border-dark`) pour s'adapter à n'importe quel preset sans une ligne de JS. Le hover sur les liens est géré avec onMouseEnter/onMouseLeave qui mutent `e.currentTarget.style.color` directement, un choix délibéré pour éviter une feuille de style ou une dépendance CSS modules tout en gardant le bundle minimal. Le séparateur de 40px entre les liens sociaux et le copyright est un simple `<div>` qui crée une pause visuelle avant la ligne légale.
Comment le coder en React
Mettre en place l'enveloppe externe
Crée un `<footer>` avec background défini à `var(--color-background-dark)` et 3rem de padding vertical. À l'intérieur, un `div` centré utilise flexbox colonne avec `alignItems: 'center'` et un gap de 1.5rem. Tous les enfants s'empilent automatiquement.
<footer style={{ background: "var(--color-background-dark)", padding: "3rem 0" }}> <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: "1.5rem" }}> {/* children */} </div> </footer>Nom de marque et description
Affiche la marque comme un `<a href='/'>` en majuscules, font-weight 700 et letter-spacing 0.05em. Enveloppe la description dans un bloc conditionnel, affiche-la uniquement si la chaîne est non vide. Limite-la à 400px de large et baisse l'opacité à 40% blanc pour qu'elle s'efface derrière la marque.
{brandDescription && ( <p style={{ color: "rgba(255,255,255,0.4)", maxWidth: "400px", textAlign: "center" }}> {brandDescription} </p> )}Rangées nav et sociaux
Les deux rangées sont `display: flex` avec un gap de 1.5rem et `flexWrap: 'wrap'` sur la nav pour qu'elle se brise sur les petits écrans. Les liens démarrent à 50% d'opacité blanche et montent à 80% au hover. Utilise onMouseEnter/onMouseLeave pour définir la couleur directement sur `e.currentTarget.style`, aucune classe CSS nécessaire.
onMouseEnter={(e) => (e.currentTarget.style.color = "rgba(255,255,255,0.8)")} onMouseLeave={(e) => (e.currentTarget.style.color = "rgba(255,255,255,0.5)")}Séparateur fin et copyright
Ajoute un `<div>` de 40px de large, 1px de haut, avec `background: var(--color-border-dark)` et 0.5rem de marge haut/bas. En dessous, le `<p>` de copyright passe à 11px (0.6875rem) à 25% d'opacité blanche, pour être légalement présent mais visuellement discret.
<div style={{ width: "40px", height: "1px", background: "var(--color-border-dark)", margin: "0.5rem 0" }} /> <p style={{ fontSize: "0.6875rem", color: "rgba(255,255,255,0.25)" }}>{copyright}</p>
Quand l'utiliser
Utilise-le sur des sites mono-page à thème sombre, des portfolios, des pages d'agence ou des landing SaaS où le footer est une ponctuation finale plutôt qu'un hub de navigation. Il fonctionne mieux quand la page porte déjà une identité visuelle forte et que le footer doit juste conclure proprement. À éviter quand tu as besoin de groupes de liens en plusieurs colonnes, d'inscription à une newsletter ou de sections légales étoffées, le layout mono-colonne n'a pas la densité nécessaire.
Utilisé par
- Stripe, Utilise des footers sombres centrés avec des rangées de liens minimales sur ses pages campagnes et landings produit.
- Loom, Footer sombre avec marque, une rangée de nav plate et une ligne de copyright discrète sur ses pages marketing.
- Framer, Footer centré minimal sur les landings produit, marque en premier avec liens sur une rangée unique.
FAQ
Puis-je ajouter une image logo à la place du nom de marque texte ?
Remplace le noeud texte de l'`<a>` par un `<img>` ou un composant SVG inline. Garde l'enveloppe anchor pour que le logo reste un lien vers l'accueil ; ajuste la largeur à celle de ton logo.
Comment changer la couleur de hover des liens du blanc vers une couleur d'accent ?
Dans le handler onMouseEnter, remplace `rgba(255,255,255,0.8)` par ta valeur d'accent, par exemple `var(--color-accent)`. Fais de même pour le reset onMouseLeave. Aucune classe CSS ni state supplémentaire nécessaire.
Ce footer est-il accessible aux utilisateurs clavier et lecteurs d'écran ?
Le composant utilise un élément `<footer>` sémantique et des balises `<a>` natives, donc la navigation clavier et les lecteurs d'écran fonctionnent sans ARIA supplémentaire. Le texte de copyright à faible opacité peut échouer au contraste WCAG AA ; ajoute un `aria-label` avec le texte complet si la conformité légale l'exige.
Pourquoi les styles hover sont-ils gérés avec du JS inline plutôt qu'une classe CSS ?
Le composant utilise des styles inline partout pour rester autonome et éviter une dépendance aux CSS modules ou une feuille de style globale. Le pattern onMouseEnter/onMouseLeave est le compromis pragmatique pour un composant simple et isolé. Si ton projet utilise Tailwind, remplacer les styles inline par des classes utilitaires et le variant `hover:` est direct.