Liquid Button
Remplissage liquide en CSS pur : un pseudo-élément circulaire s'étend depuis le centre au survol, transformant la teinte du bouton en une vague fluide — zéro JavaScript.
Vous aurez accès à la démo interactive avec un compte gratuit.
Cet effet fait partie d'Effect.Labs — 811 effets vanilla, une partie gratuite, une partie premium. Atmosphère comprend 57 effets, dont 10 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
L'effet repose entièrement sur un pseudo-élément ::before positionné en absolu au centre du bouton (top:50%; left:50%; transform:translate(-50%,-50%)). Au repos, il mesure 0×0 px et est donc invisible. Au :hover, il passe à 300×300 px avec border-radius:50% : le cercle grossit depuis le centre et son débordement est clippé par overflow:hidden sur le bouton parent, créant l'illusion d'un remplissage qui monte comme un liquide.
Deux transitions CSS indépendantes se superposent : transition:.3s sur .liquid-btn pilote d'éventuels changements de propriétés du bouton lui-même, et transition:.5s sur le ::before contrôle l'expansion du cercle. Le texte est placé dans un <span> avec position:relative; z-index:1 pour rester au-dessus du remplissage en cours d'animation.
L'effet ne touche pas au DOM, ne lance aucun requestAnimationFrame et n'expose aucune API JavaScript — c'est du CSS déclaratif pur. Les navigateurs modernes GPU-accélèrent la propriété width/height via le compositing, ce qui rend la transition fluide sans coût CPU notable. Aucune variable CSS n'est lue dynamiquement : les tailles de padding et de rayon utilisent des custom properties --space-4, --space-8 et --radius-lg définies sur :root.
Accessibilité
- prefers-reduced-motion absent dans le code : l'animation de remplissage se déclenche systématiquement au survol, quel que soit le réglage du système. Pour les utilisateurs sensibles, ajoutez
@media (prefers-reduced-motion:reduce) { .liquid-btn::before { transition:none } }. - Le
<button>natif est focusable au clavier (Tab) et activable avec Entrée ou Espace — aucune configuration supplémentaire requise. - Aucun style
:focus-visiblen'est défini dans le code ; le navigateur applique son contour par défaut (peut être peu visible sur certains OS/thèmes). Recommandé : ajouter.liquid-btn:focus-visible { outline:2px solid #818cf8; outline-offset:2px }. - Contraste texte blanc sur fond
#6366f1(indigo) : ratio ≈ 3,9:1 — passe WCAG AA pour les grandes interfaces (≥ 18 pt), mais échoue pour le texte courant (< 18 pt). Adapter la couleur de fond ou alourdir la police si nécessaire. overflow:hiddensur le bouton empêche le pseudo-élément de déborder en dehors du rayon de bordure — aucune fuite visuelle quelle que soit la taille du bouton.
Compatibilité navigateur
Nécessite uniquement ::before, transition, border-radius et overflow:hidden — disponibles depuis CSS2/3 dans tous les navigateurs modernes.
Sans support des pseudo-éléments CSS (navigateurs très anciens), le bouton s'affiche normalement avec sa couleur de fond indigo — aucune erreur, aucun JS impliqué.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<button class="liquid-btn">
<span>Libellé du bouton</span>
</button>
HTML + CSS + JS complet, prêt à coller — avec des centaines d'effets premium.
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
| background sur .liquid-btn | #6366f1 | Couleur initiale du bouton. Remplacez par la couleur brand — la couleur de remplissage devra contraster avec celle-ci. |
| background sur .liquid-btn::before | #d946ef | Couleur du cercle liquide au survol. Choisissez une couleur complémentaire ou analogue pour un effet harmonieux. |
| --radius-lg (var CSS :root) | 0.75rem | Border-radius du bouton. Passez à 100px pour une pilule, à 0 pour un rectangle franc. |
| --space-4 / --space-8 (var CSS :root) | 1rem / 2rem | Padding vertical / horizontal du bouton. Augmentez pour un bouton CTA hero, réduisez pour un contexte compact. |
| transition sur .liquid-btn::before | .5s | Durée d'expansion du remplissage. .3s = réaction vive, .8s = déploiement lent et dramatique. |
| width / height sur .liquid-btn:hover::before | 300px | Diamètre max du cercle liquide. Augmentez à 400px ou plus si votre bouton dépasse 250 px de largeur — sinon les coins restent visibles. |
| z-index sur .liquid-btn span | 1 | Maintient le texte au-dessus du remplissage. Ne pas descendre en dessous de 1 pour éviter que le texte disparaisse lors de l'animation. |
FAQ
::before, une transition sur width et height, et overflow:hidden pour le clipping. Aucun script n'est chargé, aucune dépendance npm. Intégrable dans n'importe quel framework (React, Vue, Svelte) en copiant uniquement le CSS.prefers-reduced-motion nativement. Ajoutez ce bloc CSS après l'inclusion de l'effet : @media (prefers-reduced-motion:reduce) { .liquid-btn::before { transition:none; width:100%; height:100%; border-radius:0; opacity:.15; } }. Cela désactive l'animation et affiche un léger tint statique à la place.width et height sur .liquid-btn:hover::before est fixée à 300 px. Si votre bouton est plus large (ex. bouton pleine largeur), le cercle ne remplira pas les coins. Calculez la diagonale du bouton avec Math.sqrt(w²+h²) et utilisez cette valeur (arrondie au supérieur) comme diamètre. Alternativement, remplacez width/height par une transformation : transform:translate(-50%,-50%) scale(4) sur le hover est plus robuste pour les boutons de taille variable.