Shine Sweep
Au survol, une bande blanche à 20 % d'opacité traverse le bouton de gauche à droite en 500 ms — et repasse en sens inverse quand le curseur le quitte. Un pseudo-élément, une transition, aucun JavaScript.
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
.btn-shine est un bouton plein : fond #1a1a2e, texte blanc, bordure de 1 px blanche à 10 %. Le reflet est son ::before : une boîte absolue de la taille exacte du bouton (width: 100%; height: 100%; top: 0), remplie d'un linear-gradient(90deg, transparent, rgba(255,255,255,.2), transparent) — une bande verticale douce, blanche à 20 % en son centre, transparente sur ses bords — et garée hors champ à left: -100%, c'est-à-dire entièrement à gauche du bouton.
Au :hover, left passe à 100% : la boîte parcourt deux largeurs de bouton en transition: left .5s, courbe ease par défaut. Mesuré dans Chromium sur le bouton livré (163 px de large) : left va de −163 à +163 px ; le centre de la bande entre dans le bouton vers 125 ms et en sort vers 375 ms, plus vite au milieu qu'aux extrémités. Le overflow: hidden de .demo-btn découpe tout ce qui dépasse : hors du bouton, rien n'est visible.
La transition est symétrique : quand le curseur quitte le bouton, left revient de 100 % à −100 % en 500 ms et le reflet retraverse le bouton de droite à gauche. Un survol bref inverse le mouvement à mi-course. Ce n'est pas un défaut mais une conséquence de la transition posée sur l'état de repos — l'onglet Personnaliser indique comment ne garder que l'aller.
Le ::before est une boîte positionnée : elle se peint au-dessus du fond et du texte du bouton. Comme le texte est blanc, le passage de la bande n'altère que le fond ; la lisibilité reste entière (voir Accessibilité). Le mouvement anime left, une propriété de mise en page recalculée à chaque image sur le thread principal — anodin pour un bouton, moins pour une grille : transform: translateX() ferait le même trajet en couche composée. Aucun :active, aucune ombre, aucun soulèvement : le reflet est le seul retour.
Accessibilité
- Contraste : texte blanc sur
#1a1a2e= 17:1, niveau AAA. Au passage du reflet, le fond sous les lettres s'éclaircit au plus à#1a1a2e+ 20 % de blanc (≈#484857) : encore 9:1. Livré conforme, sans retouche — un des rares boutons du catalogue dans ce cas. - prefers-reduced-motion absent du code : ajoutez
@media (prefers-reduced-motion: reduce) { .btn-shine::before { transition: none } }. La bande saute alors d'un côté à l'autre sans être vue — le bouton n'a plus aucun retour de survol ; prévoyez une alternative statique, par exemple.btn-shine:hover { border-color: rgba(255,255,255,.35) }. - Clavier : aucun
:hoverau focus..btn-shine:focus-visible::before { left: 100% }déclenche un passage du reflet à l'arrivée du focus par Tab — puis la bande reste garée à droite, invisible, jusqu'au prochain focus. L'outlinenatif n'est pas touché et reste le vrai indicateur. - Lecteurs d'écran :
content: "", rien n'est annoncé ; le nom accessible est le libellé du<button>natif, activable à Entrée et Espace. - Repérage du bouton : le fond
#1a1a2econtraste à 1,16:1 avec la page de démo#0a0a0fet sa bordure blanche à 10 % à 1,25:1 — c'est le texte qui délimite le bouton, pas sa forme. Sur une surface de la même teinte, le bouton disparaît : montez la bordure à 20–25 % de blanc ou éclaircissez le fond. Cible 52 px de haut (16 + 18 + 16 + 2 × 1), au-dessus du minimum de 44 px.
Compatibilité navigateur
Requiert la transition CSS de left, les pseudo-éléments et linear-gradient() — tous les navigateurs depuis 2012. Aucun JavaScript, zéro dépendance.
Sans transitions, la bande passe instantanément de −100 % à 100 % : rien n'est visible, le bouton reste un bouton plein ordinaire. Sans dégradés, le pseudo-élément est transparent : même résultat.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec Premium) :
<button class="demo-btn btn-shine">Shine Sweep</button>
Le code complet HTML + CSS + JS de Shine Sweep, 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 |
|---|---|---|
| transition: left .5s (CSS — ::before) | .5s | Vitesse du passage, aller comme retour. .3s : éclair ; .8s : reflet lent, presque liquide. |
| rgba(255,255,255,.2) (CSS — arrêt central du dégradé) | 20 % de blanc | Intensité du reflet. .35 se voit sur un fond moyen ; au-delà de .5 le texte blanc se fond dans la bande au moment du passage. |
| Arrêts du dégradé (CSS — transparent, .2, transparent) | 0 % / 50 % / 100 % | Largeur de la bande. transparent 40%, rgba(...) 50%, transparent 60% : un filet étroit ; ajoutez transform: skewX(-20deg) au ::before pour le reflet penché des boutons brillants. |
| linear-gradient(90deg, …) (CSS — angle) | 90deg | 110deg : bande inclinée sans skew. 180deg : la bande devient horizontale et le déplacement en left ne la fait plus traverser — à combiner avec un déplacement en top. |
| background: #1a1a2e (CSS — .btn-shine) | #1a1a2e | N'importe quel fond sombre ou saturé convient au reflet blanc. Sur un fond clair, passez la bande en rgba(0,0,0,.08) : un blanc à 20 % sur du clair ne se voit pas. |
| Aller simple (CSS — transition déplacée sur :hover) | aller-retour | Mettez transition: none sur .btn-shine::before et transition: left .5s sur .btn-shine:hover::before : à la sortie, la bande saute à sa position de départ sans être vue — un seul passage par survol. |
| left → transform (CSS — ::before) | left: -100% → 100% | Version composée : gardez left: -100% fixe, remplacez la règle de survol par transform: translateX(200%) et la transition par transform .5s. Même trajet, hors du thread principal. |
FAQ
left revient de 100 % à −100 % avec la même durée, et la bande retraverse le bouton en sens inverse. Pour un aller simple, déplacez la transition sur l'état :hover (voir Personnaliser) : le retour devient un saut instantané, invisible puisqu'il se fait hors du cadre découpé.#f3f4f6, par exemple) ne change presque pas sa luminance : la bande passe sans qu'on la voie. Trois réponses : une bande sombre (rgba(0,0,0,.08)), une bande de la couleur de marque à 25 %, ou mix-blend-mode: overlay sur le ::before pour que le blanc éclaircisse réellement le fond.@keyframes shine { from { left: -100% } to { left: 100% } } et .btn-shine::before { animation: shine 2.5s ease-in-out infinite } — le reflet passe toutes les 2,5 s, et le retour au départ se fait hors champ, donc sans être vu. Réservez-le à un seul bouton par écran et coupez-le sous prefers-reduced-motion : une animation qui tourne plus de 5 s doit pouvoir être arrêtée (WCAG 2.2.2).