Cartes✨ Premium

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.

JSState MachineClick

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

Récompense du jour — application de fidélité — Holo Pack Opening exemple 1

① Récompense du jour — application de fidélité

QuandÉcran quotidien : la série en cours, un sachet à ouvrir, une seule carte dedans — la récompense.
PourquoiLa séquence donne du poids à une petite récompense (un café) : 1,5 s d'étincelle, de lumière et de cascade pour une carte. Une carte = pas de navigation ; le retournement suffit à faire durer le moment.
RéglagesCode vendu avec une carte (Ultra, halo), --hpo-pack-w: 84px (sachet 136 px) pour tenir dans un bloc de 360 px, bouton détaché de la colonne, data-announce adapté, media query max-height neutralisée.
Booster de trois cartes — jeu de collection — Holo Pack Opening exemple 2

② Booster de trois cartes — jeu de collection

QuandOuverture de booster : trois cartes, une rare garantie, la pile s'ouvre en éventail et se parcourt.
PourquoiC'est le scénario complet du code : cascade à 130 ms, pile s0 / s1 / s2, navigation ‹ › et flèches, trois raretés — commune grise (hpo-card--common, holo à .22), rare bleue (hpo-card--rare, cadre #408cf0), Ultra avec halo pulsé. La première carte du HTML devient l'active.
RéglagesTrois blocs .hpo-card (Ultra en premier), sachet recoloré en bleu nuit, textes des cartes 8 / 6,5 px (12 / 10 px au zoom), sous-titre #4a3b18, boutons ‹ › en visibility: hidden hors inspection.
Boîte mystère après achat — trois avantages à découvrir — Holo Pack Opening exemple 3

③ Boîte mystère après achat — trois avantages à découvrir

QuandPage de remerciement e-commerce : une boîte à ouvrir, trois cartes-avantages, le code au dos de chacune.
PourquoiLe retournement 3D a un vrai verso : c'est là que va le code (.hpo-back-brand), lu à voix haute par la zone live au flip. Le sachet neuf qui arrive de la droite invite à rejouer sans jamais « refermer » une boîte ouverte.
RéglagesTrois cartes (Ultra « −10 % » en premier), .hpo-back-brand = code de réduction, sachet bordeaux, reflet ralenti à 8 s (hpo-pack-sheen), --hpo-pack-w: 84px.

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 des role="button" dont tabindex et aria-hidden sont 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 attributs data-again et data-announce n'en couvrent que deux.
  • Les deux boutons ‹ › sont masqués par opacity: 0; pointer-events: none mais 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. Ajoutez visibility: hidden (ou disabled) hors de .hpo-has-nav et hors inspection.
  • Contraste mesuré (Chromium, pixels sous le texte) : bouton #fff sur rgba(20,17,38,.9) = 18,6:1 ; indication rgba(228,228,231,.65) = 6,9:1 ; nom de carte #4a3b18 sur l'ivoire = 7,4:1 ; sous-titre de carte #7d6c42 sur 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 bloc aria-hidden : décoratifs, non soumis au seuil — mais personne ne lit 6 px.
  • Tailles : nom de carte clamp(6px, 1vw, 9px), sous-titre clamp(5px, .75vw, 7px), édition clamp(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.

Chrome 88+✓ Complet
Firefox 75+✓ Complet
Safari 14.1+✓ Complet
Edge 88+✓ Complet
Mobile iOS 14.5+✓ Complet (le tap ouvre et retourne)
Android Chrome✓ Complet (le tap ouvre et retourne)

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) :

index.html — structure
<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.&nbsp;001&nbsp;/&nbsp;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&nbsp;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&nbsp;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&nbsp;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>
🔒 Débloquer le code complet — à partir de 2,99 € le 1er mois

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éfautEffet
--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

À cause de @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.
En ajoutant des cartes : le HTML vendu n'en contient qu'une, or le JS n'ajoute 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.
Non par conception : « un sachet déchiré ne se referme pas ». 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.