Slide Reveal
Au survol, le libellé glisse vers le haut de sa propre hauteur en 400 ms et un second texte, vert, écrit dans l'attribut data-text, prend sa place. Une condition à vérifier : la zone de découpe doit avoir la hauteur du libellé — dans le code livré, les deux lignes restent visibles.
Mis à jour le
Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Boutons comprend 27 effets, dont 2 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
Le HTML porte les deux libellés en un seul élément : <span class="btn-text" data-text="Let's Go!">Hover Me</span>. Le premier est le texte du span ; le second est généré par CSS : .btn-text::after { content: attr(data-text); position: absolute; left: 0; top: 100%; color: #22c55e } — il est posé juste sous le premier, à une hauteur de ligne (18 px mesurés pour 16 px de texte en line-height: normal), aligné à gauche. Le span est display: inline-block; position: relative pour servir de repère.
Au :hover, .btn-text reçoit transform: translateY(-100%) avec transition: transform .4s cubic-bezier(.65, 0, .35, 1) — une courbe d'accélération-décélération symétrique (à mi-temps, mi-distance). Le span monte de sa hauteur et emporte son ::after : le texte vert arrive exactement là où était le blanc. Seul transform est animé — couche composée, aucun recalcul de mise en page. À la sortie, même trajet en sens inverse.
L'échange suppose que ce qui sort du cadre soit caché. Le code compte sur overflow: hidden, déclaré deux fois — sur .demo-btn et sur .btn-slide-reveal. Or la zone de découpe d'un bouton est sa boîte de padding : 16 px au-dessus et au-dessous du texte. Les libellés ne bougent que de 18 px. Mesuré dans Chromium sur le bouton livré (52 px de haut) : au repos, le texte vert est 18 px sous le blanc, dont 16 px à l'intérieur du padding — visible ; au survol, le blanc est remonté dans le padding supérieur — visible aussi. Le bouton livré se lit comme deux lignes, « Hover Me » au-dessus de « Let's Go! », au repos comme au survol : la paire glisse de 18 px, rien n'est révélé.
Il faut que la découpe ait la hauteur du libellé. Deux corrections. En CSS seul, sur le bouton : padding-top: 0; padding-bottom: 0; line-height: 50px — le span hérite d'une ligne de 50 px, top: 100% et translateY(-100%) valent 50 px, le texte reste centré et le bouton garde ses 52 px avec sa bordure. En structure : un span englobant display: inline-block; overflow: hidden; vertical-align: top autour de .btn-text, dont la découpe suit le texte quel que soit le padding. Les scènes de cette page utilisent la première ; vérifiez qu'une des deux accompagne le code que vous collez.
Accessibilité
- Contraste : blanc sur
#1e1e2e= 16,4:1 et vert#22c55esur#1e1e2e= 7,2:1 — AAA pour les deux libellés. Le fond est opaque : la couleur de la page n'entre pas en jeu. Livré conforme. - Le second libellé est lu par les lecteurs d'écran : le texte généré par
content: attr(data-text)entre dans le nom accessible dans Chrome, Firefox et Safari — le bouton s'annonce « Hover Me Let's Go! », les deux à la suite. Donnez au bouton unaria-labelexplicite (le libellé principal), ou faites du second texte une reformulation du premier plutôt qu'une information nouvelle : ce qui n'apparaît qu'au survol n'existe pas pour le clavier ni le tactile. - prefers-reduced-motion absent du code :
@media (prefers-reduced-motion: reduce) { .btn-slide-reveal .btn-text { transition: none } }— l'échange devient instantané, sans glissement. - Clavier : aucun
:hoverau focus..btn-slide-reveal:focus-visible .btn-text { transform: translateY(-100%) }reproduit l'échange à l'arrivée du focus. Le code ne retire pasoutline: l'anneau natif reste, hors de la zone découpée. - Tactile : pas de survol ; sur iOS le second libellé reste affiché après un tap (
@media (hover: hover)). Un libellé qui change au survol doit laisser le bouton identifiable par un nom stable (WCAG 3.2.4) : c'est l'aria-labelqui le garantit. Cible 52 px de haut, au-dessus du minimum de 44 px.
Compatibilité navigateur
Requiert la transition CSS de transform, content: attr() sur un pseudo-élément et overflow: hidden — tous les navigateurs depuis 2012. Aucun JavaScript, zéro dépendance.
Sans transitions, les deux libellés s'échangent instantanément au survol ; l'information est la même, le glissement manque.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec Premium) :
<button class="demo-btn btn-slide-reveal">
<span class="btn-text" data-text="Let's Go!">Hover Me</span>
</button>
Le code complet HTML + CSS + JS de Slide Reveal, prêt à coller — et les 840 effets. Ou 299 € TTC une fois, accès à vie.
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
| data-text (HTML — attribut du span) | Let's Go! | Le second libellé. Gardez-le de longueur proche du premier : le ::after est absolu dans le span, sa largeur disponible est celle du premier texte — un texte plus long passe à la ligne (mesuré : trois lignes pour « From $9 per month » sous « Pricing »). white-space: nowrap l'empêche, mais il dépassera alors à droite. |
| color: #22c55e (CSS — ::after) | #22c55e | Couleur du second libellé. inherit pour le même blanc ; une couleur d'accent pour marquer le changement d'état. |
| transition: transform .4s cubic-bezier(.65, 0, .35, 1) (CSS — .btn-text) | .4s, accélération-décélération | .25s : sec ; cubic-bezier(.34, 1.56, .64, 1) : le second texte dépasse et revient — le premier réapparaît alors brièvement par le haut. |
| top: 100% (CSS — ::after) | 100 % (dessous) | top: -100% avec translateY(100%) au survol : le second texte arrive par le haut et le premier descend. |
| left: 0 (CSS — ::after) | aligné à gauche | left: 0; right: 0; text-align: center centre un second libellé plus court sous le premier ; sans cela, il colle à gauche. |
| Zone de découpe (CSS — .btn-slide-reveal, correctif) | padding 16px 32px (deux lignes visibles) | padding: 0 32px; line-height: 50px : la découpe prend la hauteur du texte et l'échange fonctionne (voir Comment ça marche). Ou un span englobant en overflow: hidden. |
| background: #1e1e2e + border rgba(255,255,255,.1) (CSS — .btn-slide-reveal) | gris-bleu sombre | Fond opaque de votre choix. Sur un fond clair, revoyez les deux couleurs de texte : le vert #22c55e tombe à 2,3:1 sur blanc — #15803d donne 5,0:1. |
FAQ
padding: 0 32px; line-height: 50px sur .btn-slide-reveal (la découpe a alors la hauteur de la ligne), ou enveloppez le span dans un conteneur display: inline-block; overflow: hidden; vertical-align: top.::after est positionné en absolu dans .btn-text : sa largeur disponible est celle du premier libellé. Plus long, il replie ses mots. Posez white-space: nowrap sur le ::after et choisissez des libellés de longueur voisine ; si le second est plus court, centrez-le avec left: 0; right: 0; text-align: center.content: attr(data-text) est intégré au nom accessible du bouton par les navigateurs récents — « Hover Me Let's Go! ». Deux remèdes : aria-label="Hover Me" sur le bouton, qui fixe le nom quel que soit l'état ; ou un second libellé qui reformule le premier au lieu d'apporter une information, pour que la lecture double reste cohérente.