Floating Elements 3D
Trois tuiles carrées de 60 px (indigo, magenta, cyan-vert) alignées, qui montent et descendent de 20 px en s'inclinant en 3D sur une boucle de 6 s, décalée de 2 s d'une tuile à l'autre : elles ne bougent jamais ensemble, comme des objets posés sur l'eau. CSS pur, zéro JavaScript, arrêtées à des hauteurs différentes 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. 3D comprend 50 effets, dont 8 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
La racine .fx-0017-root (fond #0a0a0f, 300 px de haut au minimum) centre une rangée .floating-3d (flex, 20 px d'écart) qui porte une seule caméra pour les trois tuiles : perspective: 800px. Chaque .floating-element mesure 60 × 60 px, coins arrondis de 0,75 rem, avec son dégradé à 135° : indigo → violet, magenta → rose, cyan → vert. Les trois jouent la même animation float3d de 6 s, ease-in-out, sans fin.
La boucle tient en quatre étapes : au départ la tuile est à plat ; à 25 % elle monte de 20 px et s'incline de 10° sur ses deux axes ; à 50 % elle revient à sa hauteur, tournée de 20° autour de l'axe vertical ; à 75 % elle descend de 20 px, basculée de −10° vers l'avant ; puis elle revient au repos. Le décalage vient de animation-delay négatifs : 0 s, −2 s et −4 s. Un retard négatif fait démarrer l'animation déjà avancée, si bien que dès le premier affichage les trois tuiles sont à un tiers de boucle l'une de l'autre, sans attente ni départ groupé. Comme la caméra est commune et placée au centre de la rangée, la tuile de gauche est vue un peu de droite et celle de droite un peu de gauche : la même inclinaison ne se lit pas pareil sur les trois.
Mesuré dans Chromium 151 et Firefox 153 : environ 3 % des pixels du bloc changent toutes les 0,8 s, deux copies indépendantes, 0 erreur. Seul transform est animé. Ici chaque tuile tourne seule sous la perspective de son parent, sans volume imbriqué : même le WebKit de test (Playwright 26.5), qui aplatit les cubes et les anneaux, rend les mêmes inclinaisons (0,5 % d'écart avec Chromium sur l'image fixe). Le vrai Safari n'a pas été vérifié.
Accessibilité
- Mouvement réduit : sous
prefers-reduced-motion: reduce, un bloc limité à.fx-0017-rootarrête les trois boucles et pose chaque tuile dans une étape différente de la boucle : la première 10 px plus haut et inclinée, la deuxième tournée de 20°, la troisième 10 px plus bas et basculée. On garde l'idée d'objets qui flottent, sans mouvement. Mesuré dans Chromium et Firefox : 0 animation en cours, 0 % des pixels qui changent en 0,8 s (3 % sans la préférence). - Mouvement continu : la boucle ne s'arrête jamais ; à côté d'un texte à lire, prévoyez un moyen de la mettre en pause (WCAG 2.2.2), par exemple
animation-play-state: pausedsur un bouton ou au survol de la rangée. - Contraste : les chiffres blancs font 4,5:1 sur l'indigo mais 2,4 à 2,5:1 sur le cyan-vert, sous le seuil de 4,5:1 pour un texte de 16 px. Pour y écrire une information, foncez le dégradé ou grossissez le texte (24 px gras, seuil 3:1).
- Aucune interaction : les tuiles ne réagissent ni à la souris, ni au doigt, ni au clavier ; si elles portent des chiffres utiles, comme dans le premier exemple, ils sont lus comme du texte ordinaire.
Compatibilité navigateur
CSS (transform 3D sous perspective, animation-delay négatif, @keyframes), zéro JavaScript, aucune dépendance. Mesuré dans Chromium 151 et Firefox 153 : même flottement (0,01 % d'écart sur l'image fixe), deux copies indépendantes, 0 erreur. WebKit 26.5 (moteur de test de Playwright) : mêmes inclinaisons, le vrai Safari n'a pas été vérifié.
Sans transformations 3D, les tuiles montent et descendent à plat, sans inclinaison ; sans animation, elles restent alignées et immobiles. Leur contenu reste lisible dans les deux cas.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :
<div class="fx-0017-root">
<div class="demo-3d">
<div class="floating-3d">
<div class="floating-element">1</div>
<div class="floating-element">2</div>
<div class="floating-element">3</div>
</div>
</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 |
|---|---|---|
Amplitude (CSS — @keyframes float3d) |
±20 px, inclinaisons de 10 à 20° | ±8 px et 5° pour un flottement à peine visible ; ±30 px pour des objets plus légers. Gardez les étapes 0 % et 100 % identiques pour une boucle sans à-coup. |
Durée (CSS — 6s dans l'animation de .floating-element) |
6 s | 8 à 10 s pour une page calme. Si vous la changez, gardez des retards à un tiers et deux tiers de la durée (−2,67 s et −5,33 s pour 8 s). |
Décalage (CSS — animation-delay des :nth-child(2) et (3)) |
0 s, −2 s, −4 s | Des retards à 0 donnent trois tuiles synchrones, comme une seule pièce ; des retards irréguliers (−1,3 s, −4,1 s) font plus naturel. Négatifs, ils évitent tout départ groupé au chargement. |
Taille et écart (CSS — width / height de .floating-element, gap de .floating-3d) |
60 px, écart de 20 px | Entre 72 et 90 px, un chiffre et son unité tiennent dans la tuile. Laissez au moins 20 px d'écart : les tuiles tournent de 20° et débordent un peu sur les côtés. |
Perspective (CSS — perspective de .floating-3d) |
800px | 400 px rend l'inclinaison très visible ; 1 500 px la rend presque plate. La caméra est au centre de la rangée : plus elle est proche, plus les tuiles du bord paraissent vues de biais. |
| Nombre de tuiles (HTML et CSS) | 3 | Pour 4 tuiles, ajoutez un élément et une règle :nth-child(4) ; répartissez les retards en quarts de boucle (0, −1,5 s, −3 s, −4,5 s pour 6 s). |
FAQ
animation-delay positif ferait attendre les tuiles 2 et 4 s, immobiles et alignées, avant de partir. Un retard négatif fait démarrer l'animation comme si elle tournait déjà depuis 2 ou 4 s : dès le premier affichage, les trois tuiles sont à des moments différents de la boucle..floating-3d:hover .floating-element, .floating-3d:focus-within .floating-element { animation-play-state: paused }) ou gardez le lien à côté, comme le bouton de réservation du premier exemple.