Portal Effect
Un anneau indigo de 140 px tourne en 6 s, un arc plus clair rendant sa rotation visible, autour d'un cœur lumineux violet qui respire en 3 s, et douze particules semées autour scintillent chacune à son rythme : un portail vers une autre dimension, en CSS et quelques lignes de JavaScript qui posent les particules — une instance par copie, et un portail immobile 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-0047-root (fond #0a0a0f, 300 px de haut au minimum) contient .xr-portal, un cadre qui prend toute la largeur, coupe ce qui dépasse et centre l'anneau. .xr-portal-ring est un cercle de 140 px au bord indigo de 3 px à 60 %, sauf l'arc du haut, lavande à 95 % (border-top-color) : l'anneau tourne d'un tour complet en 6 s à vitesse constante, et c'est cet arc clair qui rend la rotation visible ; un bord uniforme qui tourne paraît immobile. Dans l'anneau, .xr-portal-inner, un disque de 110 px en dégradé radial violet, respire en 3 s : il grossit de 10 % et passe de 50 à 80 % d'opacité, puis revient.
Le JavaScript ne fait qu'une chose : pour chaque .fx-0047-root de la page, il trouve son .xr-portal et y ajoute douze .xr-portal-particle, des points de 4 px #6366f1 avec une lueur. Ils sont répartis en cercle, un tous les 30°, à une distance tirée au hasard entre 37,5 et 45 % de la largeur et de la hauteur du cadre, avec une opacité de départ elle aussi tirée au hasard. Chacun scintille en 2,4 s (l'échelle passe de 0,6 à 1,5 et l'opacité de 20 à 100 %) avec un retard négatif aléatoire : les douze ne s'allument jamais ensemble. Aucun id, aucune variable globale : deux portails sur une page ont chacun leurs douze particules (mesuré dans Chromium 151, Firefox 153 et WebKit 26).
Les positions sont des pourcentages du cadre .xr-portal : leur forme dépend donc de sa taille. Par défaut, il prend toute la largeur de la racine mais seulement la hauteur de l'anneau (140 px) ; les particules dessinent alors une ellipse très aplatie, large et basse. Donnez au cadre une taille fixe, par exemple 300 × 230 px comme dans les exemples, pour une couronne plus ronde. Le script s'exécute une fois, quand il est lu : placez-le après le HTML, ou avec defer.
Accessibilité
- Mouvement réduit : sous
prefers-reduced-motion: reduce, un bloc limité à.fx-0047-rootarrête l'anneau, fige le cœur à mi-respiration (échelle 1,05, 65 % d'opacité) et coupe le scintillement : les particules restent à leur place avec leur opacité tirée au hasard. Mesuré : 0 % de pixels changés en 0,8 s dans Chromium, Firefox et WebKit, contre 0,9 à 1,3 % en mode normal. - Contenu décoratif : le portail est fait de
divvides, que les lecteurs d'écran ignorent. Si le portail est cliquable (aller au niveau suivant, page suivante d'un conte), enveloppez-le dans un vrai lien ou un bouton avec un texte, comme « Entrer dans le pays des fées ». - Contraste : l'anneau indigo mesure 4,4:1 sur le fond sombre, au-dessus du seuil de 3:1 des éléments graphiques ; les particules sont volontairement faibles. Sur fond clair, foncez l'anneau.
- Rythme : rotation de 6 s, respiration de 3 s, scintillements de 2,4 s décalés ; aucune lumière ne clignote en bloc.
Compatibilité navigateur
CSS (animations de transform et d'opacity) + 18 lignes de JavaScript ES5 sans dépendance. Mesuré dans Chromium 151, Firefox 153 et WebKit 26 (le moteur de Safari) : 0 erreur, aucune variable globale ajoutée, douze particules dans chacune de deux copies, même arrêt sous mouvement réduit. Non vérifié sur un vrai Safari.
Sans JavaScript, le portail reste entier (anneau qui tourne, cœur qui respire) mais sans particules. Si le script est chargé avant le HTML, il ne trouve aucune racine : placez-le après, ou avec defer.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :
<div class="fx-0047-root">
<div class="xr-portal">
<div class="xr-portal-ring">
<div class="xr-portal-inner"></div>
</div>
<!-- + 12 <div class="xr-portal-particle"> ajoutées par le JS -->
</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 du cadre des particules (CSS — .xr-portal) |
Toute la largeur, hauteur de l'anneau (140 px) | Les particules sont placées en pourcentages du cadre : donnez-lui une taille fixe (width: 300px; height: 230px) pour une couronne ronde autour de l'anneau. |
| Couleurs (CSS — anneau, arc clair, cœur, particules) | Indigo rgba(99,102,241,.6), arc lavande, cœur violet, particules #6366f1 | Gardez un arc nettement plus clair que le reste du bord (border-top-color), sinon la rotation ne se voit plus. |
Vitesse de rotation (CSS — 6s de .xr-portal-ring) |
6 s par tour | 14 s pour un portail apaisant, 3 s pour un vortex. Le cœur tourne avec l'anneau, sans que cela se voie : son dégradé est rond. |
Respiration du cœur (CSS — 3s de .xr-portal-inner) |
3 s, +10 %, 50 → 80 % d'opacité | C'est le rythme principal de l'effet : 4 à 5 s pour une respiration calme, 1,5 s pour un portail instable. |
| Nombre et éloignement des particules (JS) | 12 particules, à 37,5-45 % du cadre | Changez 12 dans les deux endroits de la boucle (i < 12 et i / 12), et 75 + Math.random() * 15 pour les rapprocher ou les éloigner. |
Scintillement (CSS — fx0047Twinkle 2.4s) |
2,4 s, échelle 0,6 → 1,5, opacité 20 → 100 % | Plus lent (5 s) pour un décor calme. Si vous changez la durée, changez aussi 2.4 dans le JavaScript, qui tire les retards dans cet intervalle. |
FAQ
border-top-color), sert de repère : on le voit faire le tour en 6 s. Si vous recolorez l'anneau, gardez cette différence, ou utilisez un bord en pointillés comme dans le conte..fx-0047-root et cherche le cadre par sa classe, sans id : chaque portail reçoit ses douze particules. Mesuré avec deux copies dans Chromium, Firefox et WebKit : douze particules et quatorze animations dans chacune, aucune erreur.