Atmosphère✨ Premium

3D Bars

8 barres CSS en perspective 3D animées par synthèse sinusoïdale — rotateY oscillant par barre et double ombre portée décalée simulent le relief sans canvas.

CSS 3DDepth

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. Atmosphère comprend 57 effets, dont 10 gratuits. Découvrir la catégorie →

3 exemples d'usage

Hero / Landing — Page de présentation analytics SaaS — 3D Bars exemple 1

① Hero / Landing — Page de présentation analytics SaaS

QuandSur la page d'accueil d'un outil d'analytics, de monitoring ou de BI, pour illustrer instantanément « vos données en mouvement » avant tout texte.
PourquoiLes barres 3D condensent le concept « données vivantes » en quelques pixels — plus expressif qu'un screenshot de dashboard et sans aucune image externe à charger.
RéglagesGradient brand dans .bars-3d .bar : linear-gradient(135deg, #0ea5e9, #38bdf8, #0284c7). Perspective doublée : perspective: 1000px dans .bars-3d. Amplitude réduite : 30 + value × 60 pour un mouvement plus posé en arrière-plan.
Composant produit — Widget de métriques temps réel — 3D Bars exemple 2

② Composant produit — Widget de métriques temps réel

QuandDans un tableau de bord comme barre de tendance compacte à côté d'une valeur chiffrée (requêtes/s, revenus/heure, utilisateurs actifs).
Pourquoi8 barres dans un conteneur de 80 × 120 px suffisent à communiquer « activité en cours » sans axes ni légende — idéal pour une grille de widgets dense.
RéglagesConteneur compact : height: 80px sur .bars-3d. Barres fines : width: 14px et gap: 5px. Gradient calme aligné sur la marque.
Micro-interaction de conversion — Confirmation d'import ou de synchronisation — 3D Bars exemple 3

③ Micro-interaction de conversion — Confirmation d'import ou de synchronisation

QuandQuand un import de données, une synchronisation ou un traitement se termine avec succès, juste avant l'affichage de l'écran de récapitulatif.
PourquoiUne salve montante (hauteurs forcées à 100 px pendant 600 ms via <code>bar.style.height = '100px'</code>, puis relâchées) donne un retour visuel à l'achèvement sans animation décorative permanente.
RéglagesGradient vert pour souligner le succès : linear-gradient(135deg, #10b981, #34d399, #059669). Déclencher la salve dans le callback de validation : bars.forEach(b => b.style.height = '100px'), puis setTimeout(() => bars.forEach(b => b.style.height = ''), 700).

Comment ça marche

Le conteneur .bars-3d active la scène 3D via perspective: 500px et transform-style: preserve-3d. Chaque barre reçoit un rotateX(-10deg) fixe — elle bascule légèrement vers le spectateur — et un rotateY dynamique centré sur −15°, ce qui expose la face latérale gauche et crée l'illusion d'un pavé en volume.

À chaque frame, getSimulatedAudio(8, time, baseFreq=2) génère 8 valeurs [0–1] par superposition de deux sinusoïdes dont la fréquence croît de +0,5 par index de barre, additionnées à 20 % de bruit aléatoire. La hauteur est mappée sur 20 + value × 80 px (fourchette 20 → 100 px). Les fréquences différentes par barre cassent la synchronie et donnent un mouvement organique.

La profondeur visuelle repose sur deux box-shadow solides (sans flou) : rgba(79,70,229,.5) 4px 4px 0 et rgba(79,70,229,.3) 8px 8px 0. Ces ombres décalées à droite et en bas simulent les faces latérale droite et le dessus des barres, là où un vrai modèle 3D nécessiterait de la géométrie supplémentaire.

L'oscillation de rotateY suit -15 + Math.sin(time × 0.002 + i × 0.5) × 5 degrés : le terme i × 0.5 introduit un déphasage par index, produisant une vague de rotation progressive de gauche à droite. Toutes les animations de la page partagent un unique requestAnimationFrame ; aucun IntersectionObserver n'est présent — la boucle tourne en permanence.

Accessibilité

  • prefers-reduced-motion absent : le code ne teste pas ce média-query — la boucle RAF tourne indéfiniment quel que soit le réglage système. À implémenter avant tout déploiement accessible (ex. : if (matchMedia('(prefers-reduced-motion: reduce)').matches) return;).
  • L'élément .bars-3d ne porte ni role, ni aria-label, ni aria-hidden. Pour un usage décoratif, ajoutez aria-hidden="true" sur le conteneur racine afin que les lecteurs d'écran ignorent les barres.
  • Aucun contrôle pause/stop n'est exposé — WCAG 2.2.2 (mécanisme de pause pour toute animation auto-lancée dépassant 5 s) n'est pas respecté en l'état.
  • Les barres sont des <div> non focusables et sans rôle sémantique : correct pour du décor pur, à compléter si l'effet porte de l'information réelle (ex. données de dashboard).
  • Contraste couleur : le dégradé indigo-violet sur fond #0a0a0f dépasse le ratio 3:1 pour les éléments graphiques non textuels (WCAG 1.4.11 — conforme pour un élément décoratif).

Compatibilité navigateur

Nécessite CSS 3D transforms (perspective, transform-style, rotateX/Y) et requestAnimationFrame — disponibles depuis Chrome 36+, Firefox 16+, Safari 9+. Zéro dépendance externe.

Chrome 90+✓ Complet
Firefox 90+✓ Complet
Safari 15+✓ Complet
Edge 90+✓ Complet
Mobile iOS✓ Complet
Android Chrome✓ Complet

Si JS est désactivé, les 8 barres s'affichent statiquement avec les transformations et hauteurs du HTML initial (styles inline) — l'effet visuel est préservé, figé. Aucune erreur JS fatale.

Le code

Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :

index.html — structure
<div class="demo-preview">
  <div class="bars-3d" id="bars3d" aria-hidden="true">
    <!-- 8 <div class="bar"> créés dynamiquement par le JS -->
    <div class="bar"></div>
    <div class="bar"></div>
    <div class="bar"></div>
    <div class="bar"></div>
    <div class="bar"></div>
    <div class="bar"></div>
    <div class="bar"></div>
    <div class="bar"></div>
  </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
`.bars-3d .bar` — background linear-gradient(135deg, #6366f1, #8b5cf6, #4f46e5) Couleur et direction du dégradé des barres. Remplacez les trois hex par votre palette brand ; l'angle 135° oriente la lumière haut-gauche → bas-droit.
`.bars-3d` — perspective 500px Profondeur de la scène 3D CSS. 300 px = effet dramatique et exagéré ; 800–1000 px = inclinaison subtile, quasi-plate.
`bars3dCount` (JS, ligne const bars3dCount = 8) 8 Nombre de barres créées dynamiquement. 4 barres = graphe épuré, 16 barres = visualiseur dense (pensez à réduire width et gap en conséquence).
`.bars-3d .bar` — width 20px Largeur de chaque barre. Combinez avec gap pour équilibrer l'espace négatif selon la largeur totale du conteneur.
`.bars-3d` — gap 8px Espacement entre barres. 4 px = aspect serré et dense, 14 px = aéré et minimaliste.
`time × 0.002` dans rotateY (JS, animateBars3d) 0.002 Vitesse d'oscillation de la rotation par barre. 0.001 = vague lente, 0.004 = frémissement rapide.
`20 + data[i] × 80` dans animateBars3d (JS) min 20 px, amplitude 80 px Fourchette de hauteur. 10 + data[i] × 100 = barres rasantes à plein dynamisme ; 40 + data[i] × 40 = mouvement discret autour d'une mi-hauteur fixe.
`.bars-3d .bar` — box-shadow rgba(79,70,229,.5) 4px 4px 0, rgba(79,70,229,.3) 8px 8px 0 Ombres portées simulant les faces latérales du pavé 3D. Augmentez le décalage (6 px / 12 px) pour plus de profondeur, changez la couleur pour qu'elle reste cohérente avec le dégradé.

FAQ

Non — c'est du CSS pur : perspective, transform-style: preserve-3d et rotateX/rotateY sur des <div> ordinaires. La profondeur est renforcée par deux box-shadow décalés sans flou. Zéro canvas, zéro WebGL, zéro dépendance externe.
Remplacez getSimulatedAudio() par votre source réelle — par exemple un tableau issu de l'API Web Audio (analyser.getByteFrequencyData(buf)) ou un tableau de valeurs normalisées de votre propre API. La fonction animateBars3d n'attend qu'un tableau de valeurs entre 0 et 1 : ajustez height = 20 + data[i] * 80 en conséquence.
Non — il n'y a pas d'IntersectionObserver dans l'implémentation actuelle. La boucle requestAnimationFrame tourne en permanence. Pour économiser le CPU hors du viewport, ajoutez un observer sur .bars-3d qui positionne un flag booléen paused et fait retourner animateBars3d immédiatement quand celui-ci est vrai.