Holo Pack Opening
Un sachet holographique scellé de 104 à 138 px, une étincelle qui court sur la ligne de déchirure en 450 ms, la languette qui virevolte et s'efface, puis une à trois cartes qui sortent en cascade (130 ms d'écart) et passent en inspection : zoom ×1,5, retournement 3D au clic, flèches et Échap. Séquence de 1,56 s réglée par une machine à états data-state / data-view — 23 Ko de CSS, 17 @keyframes, 8 Ko de JS, zéro dépendance. Le HTML vendu contient une seule carte.
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. Cartes comprend 41 effets, dont 6 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
Anatomie : .hpo-scene (min-height: 470px, colonne flex, overflow: hidden, fond radial) fixe cinq variables — --hpo-pack-w: clamp(104px, 15vw, 138px), hauteur du sachet × 1,62, largeur de carte × 0,84, hauteur de carte × 1,4, --hpo-split = 13 % de la hauteur du sachet (la ligne de déchirure). .hpo-stage (2,9 largeurs de sachet) contient les cartes (absolues, invisibles, centrées dans le bas du sachet) et .hpo-pack : deux fenêtres .hpo-half (haute 13 %, basse 87 %) qui montrent chacune la même face complète .hpo-packface — base en dégradé, foil arc-en-ciel en screen à .26, texture de 1 px, reflet hpo-pack-sheen qui balaie toutes les 5,5 s, art (emoji 💠, marque, édition), deux sertissages de 15 px. Au repos les deux moitiés sont jointives : aucune couture. Le profil de déchirure — un polygone de 25 points « issu d'une marche aléatoire lissée » — n'est appliqué aux deux moitiés que pendant data-state="busy" ou une fois .hpo-gone.
Ouverture (openPack, état idle → busy) : le CSS fait les 450 premières millisecondes sur le sélecteur busy — .hpo-cutter (étincelle de 8 px et traînée de 30 px) court de left: -4% à 102% (hpo-cut .45 s), .hpo-tearline passe de scaleX(0) à 1 puis s'éteint à .78 s, les deux moitiés se pincent de ±1 px ; à .45 s, hpo-split-top (.95 s) arrache la languette vers le haut-gauche (−36 px, −58 px, rotation qui oscille de −4,5° à +9° puis 1,5°) et la fond ; .hpo-bloom (la lumière qui s'échappe) dure .85 s à partir de .44 s ; neuf étincelles i et trois traînées b, créées par le JS avec des --tx / --ty / --d / --s aléatoires, partent entre .46 et .61 s. Le JS ajoute le flash à 470 ms (.hpo-firing, .38 s), sort les cartes à 780 ms (hpo-out, une toutes les 130 ms, positions s0 / s1 / s2 = remontées de 74 à 78 % de la hauteur du sachet avec ±2,2° de rotation), passe à revealed à 1300 ms (libellé du bouton → data-again, message de la zone live → data-announce) et entre en inspection à 1560 ms.
Inspection : data-view="inspect" assombrit la scène (.hpo-dim rgba(6,5,14,.68), .4 s) ; la carte active remonte de 58 % de la hauteur du sachet et passe à scale(1.5), les autres vont derrière à ±0,92 largeur de carte, scale(.8), ±6°, brightness(.45). La carte Ultra (sans classe --common ni --rare) reçoit .hpo-card--glowing : un reflet arc-en-ciel de 4,5 s et une pulsation de drop-shadow de 2,8 s ; l'étoile pulse en 2 s. Un clic sur la carte active bascule .hpo-flipped → .hpo-flip3d tourne de 180° en .55 s (deux faces en backface-visibility: hidden, le dos est un panneau indigo avec 💠 et la marque). Un clic sur une carte de derrière, les boutons ‹ › (montrés seulement avec .hpo-has-nav, c'est-à-dire n > 1) ou les flèches changent la carte active ; chaque changement met à jour tabindex, data-pos et la zone live.
Nouveau sachet (bouton ou Échap, état revealed → busy) : le sachet déchiré est jeté à gauche (hpo-discard-pack .45 s : −96 px, +44 px, −11°), les cartes se dissolvent en lumière (hpo-card-dissolve .62 s, brightness 2,1 → 3, l'active en dernier, 90 ms d'écart), puis serveNew() remet les classes à zéro et fait glisser un sachet scellé depuis la droite (hpo-arrive-in .55 s) — 430 + (n − 1) × 90 + 660 ms, soit ≈ 1,1 s pour une carte. Sous prefers-reduced-motion, le JS saute tous les minuteurs (languette retirée, cartes empilées, inspection immédiate) et le CSS annule les 17 animations. Le HTML vendu contient une seule carte : la cascade, la pile et la navigation existent dans le code, mais demandent de dupliquer le bloc .hpo-card (classes de rareté hpo-card--common / hpo-card--rare). Deux restes du catalogue : @media (max-height: 360px) { .hpo-scene { transform: scale(.52) } }, écrit pour l'iframe d'aperçu, et .hpo-high-contrast, miroir d'un interrupteur de démo ; hpo-tearing est retiré par le JS sans jamais être ajouté.
Accessibilité
- Une zone
aria-live="polite"annonce chaque étape ; les cartes sont desrole="button"donttabindexetaria-hiddensont gérés (masquées dans le sachet, focus donné à l'active en inspection) ; Entrée et Espace retournent, Échap sert un nouveau sachet. Mais toutes les phrases annoncées sont codées en français dans le JS (« Carte 1 sur 3 : … », « Dos de la carte. », « Ouvrir un autre pack » par défaut) — les attributsdata-againetdata-announcen'en couvrent que deux. - Les deux boutons ‹ › sont masqués par
opacity: 0; pointer-events: nonemais restent dans l'ordre de tabulation : mesuré dans Chromium, Tab s'arrête deux fois sur eux avant d'atteindre le bouton d'ouverture — deux arrêts de focus invisibles, sur une page qui n'a qu'une carte. Ajoutezvisibility: hidden(oudisabled) hors de.hpo-has-navet hors inspection. - Contraste mesuré (Chromium, pixels sous le texte) : bouton
#fffsurrgba(20,17,38,.9)= 18,6:1 ; indicationrgba(228,228,231,.65)= 6,9:1 ; nom de carte#4a3b18sur l'ivoire = 7,4:1 ; sous-titre de carte#7d6c42sur l'ivoire#dcd2b8 → #f2ecdc= 3,4 à 4,35:1, sous 4,5:1 →#4a3b18(7,2 à 9,2:1) ou#5c4d2a(5,5 à 7,0:1). Les textes du sachet (marque 6,5 à 12:1, édition 6,4 px à 1,4–5,8:1 selon le reflet) sont dans un blocaria-hidden: décoratifs, non soumis au seuil — mais personne ne lit 6 px. - Tailles : nom de carte
clamp(6px, 1vw, 9px), sous-titreclamp(5px, .75vw, 7px), éditionclamp(6px, .8vw, 8px)— de 5 à 9 px, illisibles par construction (la carte fait 87 à 116 px de large) ; seul le zoom ×1,5 de l'inspection porte le nom à 9–13 px. Si la carte porte un sens (nom de la récompense), écrivez-le aussi hors de la carte. - Mouvement réduit géré dans le CSS (17 animations annulées, transitions à .01 s) et dans le JS (aucun minuteur : révélation instantanée) ; transparence réduite : foil et couches holo masquées, voile porté à .92. L'emoji 💠 (trois occurrences) dépend de la police du système et est
aria-hidden. Rien ne bloque le défilement tactile ; le bouton d'ouverture fait 40 px de haut (44 recommandés).
Compatibilité navigateur
Requiert clip-path: polygon(), clamp(), inset, backface-visibility, filter: drop-shadow() animé, mix-blend-mode et les variables CSS dans calc(). JavaScript ES5. Aucune bibliothèque.
Sans JavaScript rien ne s'ouvre : sachet scellé, bouton inerte, seul le reflet du sachet tourne. Sans clip-path, la déchirure est rectiligne mais les deux moitiés se séparent quand même. Sous prefers-reduced-motion la révélation est instantanée et l'inspection s'ouvre directement.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="hpo-scene" id="hpoScene" data-state="idle" data-again="Ouvrir un autre pack" data-announce="Carte Ultra Rare holographique révélée. Cliquer pour la retourner.">
<div class="hpo-bg-glow" aria-hidden="true"></div>
<div class="hpo-stage">
<div class="hpo-card" role="button" tabindex="-1" aria-label="Carte Ultra Rare — cliquer pour la retourner" aria-hidden="true">
<div class="hpo-flip3d">
<div class="hpo-face hpo-face--front">
<div class="hpo-card-bg"></div>
<div class="hpo-card-holo"></div>
<div class="hpo-card-sheen"></div>
<div class="hpo-card-content">
<div class="hpo-card-icon" aria-hidden="true">★</div>
<div class="hpo-card-name">Ultra Rare</div>
<div class="hpo-card-sub">No. 001 / HOLO</div>
</div>
<div class="hpo-card-frame"></div>
</div>
<div class="hpo-face hpo-face--back">
<div class="hpo-back-inner">
<div class="hpo-back-gem" aria-hidden="true">💠</div>
<div class="hpo-back-brand">Effect Labs</div>
</div>
</div>
</div>
</div>
<div class="hpo-pack" aria-hidden="true">
<div class="hpo-half hpo-half--top">
<div class="hpo-packface">
<div class="hpo-packface-base"></div>
<div class="hpo-packface-foil"></div>
<div class="hpo-packface-texture"></div>
<div class="hpo-packface-sheen"></div>
<div class="hpo-packface-art">
<div class="hpo-packface-gem">💠</div>
<div class="hpo-packface-brand">
Effect
<br>
Labs
</div>
<div class="hpo-packface-edition">Édition Rare</div>
</div>
<div class="hpo-packface-crimp-top"></div>
<div class="hpo-packface-crimp-bot"></div>
</div>
</div>
<div class="hpo-half hpo-half--bot">
<div class="hpo-packface">
<div class="hpo-packface-base"></div>
<div class="hpo-packface-foil"></div>
<div class="hpo-packface-texture"></div>
<div class="hpo-packface-sheen"></div>
<div class="hpo-packface-art">
<div class="hpo-packface-gem">💠</div>
<div class="hpo-packface-brand">
Effect
<br>
Labs
</div>
<div class="hpo-packface-edition">Édition Rare</div>
</div>
<div class="hpo-packface-crimp-top"></div>
<div class="hpo-packface-crimp-bot"></div>
</div>
</div>
<div class="hpo-tearline" aria-hidden="true"></div>
<div class="hpo-cutter" aria-hidden="true"></div>
<div class="hpo-bloom" aria-hidden="true"></div>
<div class="hpo-burst" aria-hidden="true"></div>
</div>
</div>
<div class="hpo-dim" aria-hidden="true"></div>
<div class="hpo-flash" aria-hidden="true"></div>
<button class="hpo-nav hpo-nav--prev" type="button" aria-label="Carte précédente">‹</button>
<button class="hpo-nav hpo-nav--next" type="button" aria-label="Carte suivante">›</button>
<p class="hpo-hint" aria-hidden="true">Cliquer : retourner la carte · Échap : autre pack</p>
<button class="hpo-trigger" type="button" aria-label="Ouvrir le pack holographique">Ouvrir le pack</button>
<div class="hpo-announce" aria-live="polite" aria-atomic="true"></div>
</div>
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 |
|---|---|---|
--hpo-pack-w (CSS — .hpo-scene) |
clamp(104px, 15vw, 138px) | Toutes les dimensions en découlent : sachet × 1,62, carte × 0,84 et × 1,4, stage 2,9 largeurs. En vw, la taille dépend de la fenêtre, pas du conteneur — fixez une valeur en px dans un widget. Retirez aussi min-height: 470px. |
| Nombre de cartes (HTML — blocs .hpo-card) | 1 | Dupliquez le bloc ; hpo-card--common / hpo-card--rare pour les raretés, aucune classe = Ultra avec halo. Le JS ajoute hpo-has-nav dès deux cartes. Au-delà de trois, les positions s2 / behind2 se superposent. |
| Tempo (JS — 470 / 780 / 1300 / 1560 ms ; CSS — .45s / .95s) | 1,56 s jusqu'à l'inspection | Les délais JS sont calés sur les durées CSS (étincelle .45 s, arrachage .95 s dès .45 s) : décalez-les ensemble. Supprimez le setTimeout(enterInspect, 1560) pour laisser les cartes en pile. |
| Cascade (JS — stackCards(130)) | 130 ms | Écart entre deux cartes qui sortent. 0 = sortie simultanée ; 250 = une par une. |
| Zoom d'inspection (CSS — [data-view="inspect"] [data-pos="active"]) | scale(1.5), remontée de 58 % | Agrandissement de la carte active. 1.8 pour lire un texte ; ajustez la remontée pour rester dans la scène, qui est en overflow: hidden. |
| Textes (HTML — data-again / data-announce ; JS — say()) | français | Libellé du bouton après ouverture et message d'annonce dans le HTML ; les autres phrases (« Carte x sur n », « Dos de la carte ») sont dans le JS — traduisez-les là. |
| Matière du sachet (CSS — .hpo-packface-base / -foil / -sheen) | violet, foil .26, reflet 5,5 s | Base en trois dégradés, arc-en-ciel en screen, reflet hpo-pack-sheen. Baissez l'opacité de la foil à .12 pour un sachet mat ; allongez le reflet à 8 s pour un rythme calme. |
FAQ
@media (max-height: 360px) { .hpo-scene { transform: scale(.52); transform-origin: 50% 30% } }, une règle écrite pour l'iframe d'aperçu du catalogue : elle réduit toute la scène à 52 % dès que la fenêtre fait 360 px de haut ou moins, quel que soit votre conteneur. Supprimez-la et dimensionnez par --hpo-pack-w ; retirez aussi min-height: 470px si le bloc est plus bas.hpo-has-nav (qui affiche ‹ › et active les flèches) qu'à partir de deux, et la pile s0 / s1 / s2 est prévue pour trois. Dupliquez le bloc .hpo-card, donnez à chacune sa rareté (hpo-card--common, hpo-card--rare, ou rien pour l'Ultra qui brille) et mettez en premier celle qui doit être active à l'ouverture. Les positions behind1 / behind2 n'accueillent que deux cartes derrière l'active.newPack() jette l'ancien, dissout les cartes et sert un sachet neuf (≈ 1,1 à 1,3 s) ; la machine à états idle / busy / revealed ignore les clics pendant l'animation et désactive le bouton. Attention : Échap est écouté sur document dès l'état revealed — il déclenchera un nouveau sachet même si le focus est ailleurs, par exemple dans une modale.