Neu Card
Une carte de 280 px en relief (ombres 10 px / 20 px), un avatar de 56 px creusé dans la même matière et une jauge de 8 px en creux remplie d'un dégradé violet qui respire toutes les 2 s : relief et creux réunis dans un seul bloc, pur CSS.
Mis à jour le
Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Glassmorphism comprend 47 effets, dont 6 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
Trois niveaux de profondeur, tous dans la teinte #e0e5ec. La carte .neu-card (280 px de large, padding: 28px, border-radius: 20px, colonne flex avec 16 px d'écart) sort de la surface par deux ombres opposées : #b8bec7 10px 10px 20px et #fff -10px -10px 20px. Au survol, elles s'élargissent à 14 px / 28 px en 0,3 s : la carte monte vers le doigt. L'avatar .neu-card-avatar (56 px, rond) fait l'inverse : ombres internes inset 4px 4px 8px, il est creusé dans la carte, et son icône SVG est tracée en violet #8b5cf6 à 1,5 px. Le titre h3 (16 px, 700, #374151) et le texte (13,1 px, #6b7280, interligne 1,5) n'ont pas d'effet propre.
La jauge .neu-card-bar est une rigole de 8 px (ombres internes 2 px / 4 px, overflow: hidden). Son remplissage .neu-card-bar-fill occupe 72 % par défaut, dégradé #8b5cf6 → #a78bfa avec un halo violet de 8 px, et porte l'animation neuBarPulse : opacité 1 → 0,7 → 1 sur 2 s en ease-in-out, en boucle. C'est le seul mouvement de l'effet — il signale une valeur « vivante » (une charge, une progression) sans rien déplacer. Le taux se change en une ligne : width sur le remplissage.
La carte apporte sa propre surface, parce que le neumorphisme dépend entièrement du fond : posée sur un noir comme #0a0a0f, l'ombre #fff -10px -10px 20px dessinerait un halo blanc tout autour, le contraire d'un relief. .neu-card-scene déclare donc background: #e0e5ec, padding: 44px (assez pour l'ombre de survol, 14 + 28 = 42 px) et border-radius: 24px. Mesuré dans Chromium et Firefox, collée dans une page blanche puis noire : l'ombre claire tombe sur la matière, rien ne déborde sur le fond de la page.
Accessibilité
- prefers-reduced-motion absent du code : la pulsation de la jauge tourne en boucle même quand le système demande moins d'animation. Elle est douce (opacité seulement, pas de déplacement), mais infinie : ajoutez
@media (prefers-reduced-motion: reduce) { .neu-card-bar-fill { animation: none } }, la jauge reste lisible à plein. - Contraste : le titre
#374151sur#e0e5ecmesure 8,1:1, mais le texte#6b7280(13,1 px) seulement 3,8:1, sous le seuil de 4,5:1 — passez-le en#4b5563(6,0:1). Le remplissage violet contre la rigole va de 3,3:1 au départ à 2,2:1 en bout de dégradé (#a78bfa), sous les 3:1 demandés aux éléments graphiques : pour une jauge porteuse d'information, finissez le dégradé sur#7c3aedou écrivez la valeur en clair. Les bords de la carte, eux, n'existent que par l'ombre#b8bec7(1,5:1) : ne confiez pas à la seule forme de la carte une information importante. - Jauge muette :
.neu-card-barest undivsans rôle, un lecteur d'écran n'en dit rien. Ajoutezrole="progressbar",aria-valuenow,aria-valuemin,aria-valuemaxet unaria-label, ou écrivez la valeur en clair sous la jauge (« Batterie 72 % ») — les trois scènes font les deux. - Icône : le SVG de l'avatar n'a pas de texte alternatif ; s'il est décoratif, posez
aria-hidden="true". La carte n'est pas interactive (le survol est purement visuel) : rien à atteindre au clavier, et si vous la rendez cliquable, enveloppez-la dans un vrai lien ou bouton.
Compatibilité navigateur
CSS seul : box-shadow multiple et inset, linear-gradient, @keyframes sur opacity, flexbox avec gap. Zéro JavaScript, zéro dépendance. Rendu mesuré identique dans Chromium, Firefox et WebKit (Playwright). Le gap des conteneurs flex demande Chrome 84, Firefox 63, Safari 14.1. La carte fait 280 px marge intérieure comprise parce que le bloc .demo-preview du code pose box-sizing: border-box ; si vous ne gardez pas ce bloc, elle passe à 336 px (280 + 2 × 28) — ajoutez box-sizing: border-box à .neu-card pour garder 280.
Avant le gap des conteneurs flex, les éléments de la carte se collent les uns aux autres : ajoutez des marges si vous visez Safari 14.0 ou plus ancien. Sans animation CSS, la jauge reste pleine et immobile.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec Premium) :
<div class="demo-preview">
<div class="neu-card-scene">
<div class="neu-card">
<div class="neu-card-avatar"><svg viewBox="0 0 24 24">…</svg></div>
<h3>…</h3>
<p>…</p>
<div class="neu-card-bar">
<div class="neu-card-bar-fill"></div>
</div>
</div>
</div>
</div>
Le code complet HTML + CSS + JS de Neu Card, prêt à coller — et les 840 effets. Ou 299 € TTC une fois, accès à vie.
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Taux de la jauge (CSS — .neu-card-bar-fill { width: 72% }) |
72 % | Posez la valeur en ligne (style="width: 40%") ou en JavaScript ; pensez à mettre à jour aria-valuenow en même temps. |
Pulsation (CSS — animation: 2s … neuBarPulse, opacité 1 → 0,7) |
2 s, en boucle | animation: none pour une jauge fixe (valeur atteinte, charge terminée). Ralentir à 3s la rend plus calme ; descendre l'opacité basse sous 0,5 la fait clignoter. |
Relief de la carte (CSS — 10px 10px 20px, survol 14px 14px 28px) |
10 px / 20 px | Réduisez à 6 px / 12 px pour une liste de plusieurs cartes serrées. Le padding de .neu-card-scene doit rester supérieur à décalage + flou du survol (42 px par défaut, d'où 44 px). |
Teinte de la matière (CSS — #e0e5ec, ombres #b8bec7 / #fff) |
gris bleuté clair | Changez fond, carte, avatar et rigole ensemble, avec une ombre plus sombre et une plus claire de la même famille. Exemple crème : #efe9e1, ombres #d3cbc0 et #ffffff. |
Couleur de la jauge (CSS — linear-gradient(135deg, #8b5cf6, #a78bfa)) |
violet | Vert batterie #16a34a → #4ade80, ambre #d97706 → #fbbf24. Changez aussi le halo box-shadow: rgba(…, .4) 0 0 8px et l'icône de l'avatar (stroke). |
FAQ
.neu-card-bar-fill { width: 72% } dans le code vendu. Écrivez la vôtre en ligne (style="width: 40%") ou en JavaScript : fill.style.width = valeur + '%'. Pour que la barre glisse au lieu de sauter, ajoutez transition: width .4s ease au remplissage. Donnez aussi un sens à la barre pour les lecteurs d'écran : role="progressbar", aria-valuemin="0", aria-valuemax="100" et aria-valuenow sur .neu-card-bar, mis à jour avec la largeur. Une fois la valeur atteinte, animation: none arrête la respiration.gap d'au moins 40 px, pour que les ombres ne se chevauchent pas) plutôt que de répéter .neu-card-scene autour de chacune.