Underline Expand
Un soulignement de 2 px naît au centre du lien et s'étend symétriquement vers les bords au survol — CSS pur, zéro JavaScript.
Cet effet est gratuit — la catégorie Navigation en contient 36 au total, dont 4 gratuits. Effect.Labs regroupe 811 effets vanilla. Découvrir la catégorie →
Exemples d'usage
Créez plus vite,
lancez en confiance
La plateforme qui évolue avec votre équipe. Du prototype à la production en quelques minutes.
Comment ça marche
L'effet repose sur un pseudo-élément ::after ancré au centre du lien via left: 50% et transform: translateX(-50%). Au repos, width: 0 le rend invisible. Au survol, width: 100% le fait croître symétriquement vers les deux bords simultanément — c'est ce centrage qui crée l'illusion d'une expansion depuis le milieu et non depuis un bord.
Le fond du trait utilise var(--gradient-primary) : il hérite du dégradé défini dans le thème hôte. La transition CSS de 0,3 s (transition: 0.3s sur ::after) anime la largeur de façon fluide, sans aucun calcul JavaScript ni mesure de position au runtime.
Parallèlement, la couleur du texte passe de var(--text-secondary) à var(--text-primary) via sa propre déclaration transition: color 0.3s. Les deux transitions ciblent des propriétés distinctes et s'exécutent sans conflit — l'une anime width sur ::after, l'autre anime color sur l'élément parent.
L'effet est entièrement déclaratif : pas de JS, pas d'écouteur d'événement. Ajoutez la classe .link-underline-expand à tout élément <a>, <span> ou <button> disposant de position: relative pour l'activer immédiatement.
Accessibilité
- prefers-reduced-motion absent du code : la transition de 0,3 s s'exécute même si l'OS signale une préférence pour réduire le mouvement. Correctif recommandé :
@media (prefers-reduced-motion: reduce) { .link-underline-expand::after { transition: none; } }. - L'effet est purement décoratif : la couleur du texte change également au survol, offrant un second indicateur d'état indépendant du soulignement — utile pour les utilisateurs daltoniens ou qui désactivent les pseudo-éléments.
- Le code de démonstration utilise des
<span>— en production, utilisez des<a>natifs et ajoutez.link-underline-expand:focus-visible::after { width: 100%; }pour activer l'effet au clavier. - Le contraste dépend des variables CSS du thème hôte. Sur le thème dark Effect.Labs,
--text-secondary(#a1a1aa sur #0a0a0f) atteint un ratio de ~4,6:1, conforme WCAG AA. - L'effet n'ajoute que de l'information visuelle — aucun contenu n'est masqué ni retiré du flux, aucun impact sur les lecteurs d'écran.
Compatibilité navigateur
Requiert ::after, transitions CSS et propriétés CSS custom (var()) — supportés dans tous les navigateurs modernes depuis 2017.
Sans propriétés CSS custom (<code>var()</code>), les couleurs par défaut du navigateur s'appliquent. Sans transitions CSS, le soulignement apparaît et disparaît instantanément — fonctionnel mais sans animation.
Le code
Copiez les trois blocs dans votre page. Aucune dépendance.
<div class="nav-demo">
<span class="nav-link-demo link-underline-expand">Accueil</span>
<span class="nav-link-demo link-underline-expand">Services</span>
<span class="nav-link-demo link-underline-expand">Contact</span>
</div>
.nav-demo {
display: flex;
gap: var(--space-8);
align-items: center;
}
.nav-link-demo {
color: var(--text-secondary);
font-weight: 500;
padding: var(--space-2) 0;
position: relative;
cursor: pointer;
transition: color 0.3s;
}
.nav-link-demo:hover {
color: var(--text-primary);
}
.link-underline-expand::after {
content: "";
position: absolute;
bottom: 0px;
left: 50%;
width: 0px;
height: 2px;
background: var(--gradient-primary);
transition: 0.3s;
transform: translateX(-50%);
}
.link-underline-expand:hover::after {
width: 100%;
}
// Effet CSS pur — pas de JavaScript nécessaire
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
| var(--gradient-primary) | dégradé indigo→violet→rose | Couleur ou dégradé du soulignement. Remplacez par une couleur unie (#6366f1) ou un dégradé personnalisé. |
| height: 2px (dans ::after) | 2px | Épaisseur du trait. 1 px = ultra-discret, 3–4 px = affirmé. |
| bottom: 0px (dans ::after) | 0px | Décalage vertical sous la ligne de base. Une valeur négative comme -4px éloigne le trait du texte. |
| transition: 0.3s (dans ::after) | 0.3s | Durée de l'animation d'expansion. 0,15 s = réactif, 0,5 s = cinématique. |
| width: 100% (dans :hover::after) | 100% | Largeur maximale au survol. 80% donne un trait légèrement plus court que le texte, ancré au centre. |
| var(--text-secondary) / var(--text-primary) | #a1a1aa / #ffffff | Couleurs du texte au repos et au survol, définies dans le thème hôte. |
| var(--space-8) (gap de .nav-demo) | 2rem | Espacement entre les liens. Réduisez à 1rem pour une navigation plus compacte. |
FAQ
Le soulignement peut-il s'arrêter à 80 % de la largeur plutôt que couvrir tout le lien ?
Oui — modifiez .link-underline-expand:hover::after { width: 80%; }. Le trait reste ancré au centre grâce à left: 50% + translateX(-50%), il sera toujours centré sous le texte quelle que soit la largeur cible.
Comment déclencher l'effet au focus clavier et pas seulement au survol souris ?
Ajoutez .link-underline-expand:focus-visible::after { width: 100%; } dans votre CSS. Cela active le soulignement lors de la navigation au clavier (Tab) avec la même transition, sans affecter le comportement souris.
Peut-on combiner un soulignement statique au repos avec l'effet expand au survol ?
Oui — définissez une largeur non nulle au repos, par exemple .link-underline-expand::after { width: 20%; }. Le survol la fera passer à 100% avec la transition, créant un effet de croissance plutôt qu'une apparition depuis zéro.