Shape Shifter
Un bloc découpé par clip-path qui se déforme à chaque clic, du cercle au carré, au triangle, à l'hexagone puis à l'étoile, en 0,8 s : les cinq formes sont des polygones de 40 points, donc chaque point glisse vers le sien, et le dégradé change de teintes en même temps. Le découpage s'applique à tout ce que le bloc contient, photo comprise ; vrai bouton au clavier, forme posée sans déformation si l'utilisateur réduit les animations.
Mis à jour le
Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Liquid comprend 31 effets, dont 6 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
Le bouton .shape-shifter-btn entoure un bloc de 140 × 140 px, .shape-shifter, dont l'attribut data-shape choisit la forme : circle, square, triangle, hexagon ou star. Chaque valeur a sa règle CSS, un clip-path: polygon(…) et deux couleurs de dégradé. Au clic (ou Entrée, Espace), le script passe à la forme suivante et écrit son nom sous le bloc, dans .shape-label, en le lisant dans l'attribut data-names du bouton (« Cercle,Carré,Triangle,Hexagone,Étoile »). La déformation elle-même est une transition CSS : transition: clip-path .8s cubic-bezier(.68, -.2, .27, 1.2), avec un léger recul au départ et un léger dépassement à l'arrivée.
Un navigateur ne sait interpoler deux clip-path que s'ils utilisent la même fonction avec le même nombre de points : entre circle() et polygon(), ou entre un carré de 4 sommets et une étoile de 10, il saute d'un coup. C'est pourquoi les cinq formes sont écrites en polygon() de 40 points, tous partant du haut au centre et tournant dans le même sens : le cercle est un polygone de 40 côtés (écart au vrai cercle inférieur à 0,3 px à 140 px), et chaque côté du carré, du triangle, de l'hexagone et de l'étoile porte ses points intermédiaires. Mesuré image par image dans Chromium 151, Firefox 153 et WebKit 26 : sur chacun des cinq passages, l'aire découpée change à chaque image (du cercle au carré, l'aire passe de 78 % à 64 % du bloc par 83 à 86 valeurs différentes dans Chromium et Firefox, 24 dans WebKit, qui dessine moins d'images en mode sans écran).
Les deux couleurs du dégradé, --fx0403-c1 et --fx0403-c2, sont déclarées avec @property comme des <color> : le navigateur sait alors les faire glisser en 0,8 s, en même temps que la forme, alors qu'un linear-gradient() écrit en dur changerait d'un bloc. Un clic pendant la déformation repart de la forme affichée, la transition CSS se réoriente seule. Le découpage porte sur .shape-shifter et sur tout son contenu : une photo, une illustration ou un texte placés dedans prennent la forme, comme le portrait de la carte de judo dans les exemples.
Accessibilité
- Clavier et lecteurs d'écran : la forme est dans un vrai
<button>nommé « Forme suivante ». Mesuré dans Chromium et Firefox : Tab l'atteint, Entrée et Espace font passer à la forme suivante. Le libellé.shape-labelportearia-live="polite": le nom de la nouvelle forme est annoncé. Dans Safari, Tab ne s'arrête sur les boutons que si le réglage clavier le demande (ou avec Option+Tab). - Anneau de focus : le découpage est porté par l'enfant
.shape-shifter, pas par le bouton, pour que l'anneau de focus (2 px cyan, décalé de 6 px) reste entier autour de la forme. - Mouvement réduit : sous
prefers-reduced-motion: reduce,clip-pathn'a plus de transition, seules les couleurs passent en 0,4 s. Mesuré : la nouvelle forme est en place dès la première image. - La forme ne doit pas être la seule information : si elle a un sens (un cadre choisi, un pion), le libellé le dit aussi en texte, comme dans les exemples.
Compatibilité navigateur
CSS (clip-path: polygon(), @property) + 1 Ko de JavaScript, aucune dépendance. Mesuré image par image dans Chromium 151, Firefox 153 et WebKit 26 : même déformation sur les cinq passages, mêmes couleurs qui glissent, même arrêt sous mouvement réduit. clip-path: polygon() s'anime depuis Chrome 55, Firefox 54 et Safari 13.1. @property existe depuis Chrome 85, Safari 16.4 et Firefox 128 ; sans lui, les couleurs changent d'un coup mais la forme se déforme quand même. Coût : un bloc de 140 px repeint pendant 0,8 s, négligeable.
Sans JavaScript, le bloc reste en cercle. Sans @property, le dégradé saute d'une teinte à l'autre pendant que la forme se déforme. Un navigateur sans clip-path affiche le bloc carré de 140 px, avec son dégradé.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :
<div class="fx-0403-root">
<div class="shape-shifter-container">
<button type="button" class="shape-shifter-btn" aria-label="Forme suivante"
data-names="Cercle,Carré,Triangle,Hexagone,Étoile">
<span class="shape-shifter" data-shape="circle"></span>
</button>
<span class="shape-label" aria-live="polite">Cercle</span>
</div>
</div>
Paiement unique, sans abonnement — le code est à toi pour toujours
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Taille (CSS — width / height de .shape-shifter) |
140 × 140 px | Les polygones sont en pourcentages : la forme suit la taille du bloc. Gardez un bloc carré, sinon le cercle devient une ellipse. |
Couleurs par forme (CSS — --fx0403-c1 / --fx0403-c2 dans chaque règle [data-shape=…]) |
cinq dégradés cyan, violet, rose, ambre, vert | Mettez les deux mêmes couleurs dans les cinq règles pour un fond fixe (un miroir, une photo sur un fond uni). Les propriétés restent animables tant que les deux @property sont présents. |
Durée et rebond (CSS — transition: clip-path .8s cubic-bezier(.68, -.2, .27, 1.2)) |
0,8 s, léger recul puis léger dépassement | .5s ease-in-out donne une déformation plus nette, sans rebond. Changez aussi la durée des deux couleurs, sinon elles finissent après la forme. |
Libellés (HTML — data-names du bouton) |
« Cercle,Carré,Triangle,Hexagone,Étoile » | Cinq noms séparés par des virgules, dans l'ordre des formes. Le script relit l'attribut à chaque clic : vous pouvez le changer à la volée (langue, prix ajouté). |
Ordre et choix des formes (JS — var shapes = ['circle', 'square', 'triangle', 'hexagon', 'star']) |
cinq formes, en boucle | Retirez une valeur pour sauter une forme (gardez data-names dans le même ordre). Une nouvelle forme demande une règle [data-shape=…] avec un polygon() de 40 points, partant du haut au centre, dans le sens des aiguilles d'une montre. |
Ombre qui suit la forme (CSS — sur .shape-shifter-btn) |
aucune (le box-shadow du bloc est découpé avec lui) |
filter: drop-shadow(0 10px 14px rgba(0,0,0,.35)) sur le bouton dessine une ombre qui épouse la forme pendant toute la déformation. |
FAQ
circle() à polygon(), la forme saute à l'arrivée, sans image intermédiaire. Il faut la même fonction et le même nombre de points des deux côtés. 40 points suffisent pour qu'un cercle de 140 px paraisse lisse (écart inférieur à 0,3 px) et se partagent proprement entre les côtés : 4 points par branche d'étoile, 10 par côté de carré. Plus de points lisseraient encore le cercle sur un très grand bloc, au prix d'un CSS plus long.polygon() de 40 points en pourcentages, dont le premier point est en haut au centre (50% y%) et qui tourne dans le sens des aiguilles d'une montre, comme les cinq autres. Répartissez les points le long des côtés, sommets compris : une forme à 5 côtés égaux reçoit 8 points par côté. Si les points de départ ne se correspondent pas, la forme se vrille pendant la déformation au lieu de se transformer proprement.