CHOISISSEZ VOTRE GENRE
Neon Glow Pulse
Éléments bordés qui pulsent via des couches de box-shadow empilées — trois variantes néon désynchronisées (rose, cyan, vert) sur fond sombre, 100 % CSS, aucun script.
Cet effet est gratuit — la catégorie Backgrounds en contient 50 au total, dont 6 gratuits. Effect.Labs regroupe 811 effets vanilla. Découvrir la catégorie →
Exemples d'usage
MON STACK
Comment ça marche
L'effet repose entièrement sur box-shadow multi-valeur : chaque élément empile jusqu'à cinq ombres extérieures (5 px, 10 px, 20 px, 50 px, 80 px de flou) et une ombre intérieure. Entre les keyframes 0 %/100 % (halo retenu : 5 px, 10 px, 20 px + inset 10 px) et 50 % (halo maximal : 10 px, 25 px, 50 px, 80 px + inset 20 px), le navigateur interpole les rayons de diffusion — c'est cette interpolation continue qui crée l'impression de respiration lumineuse.
Le text-shadow applique deux couches sur le texte lui-même (10 px et 20 px de flou) dans la même couleur que la bordure et le halo. Les propriétés color, border : 2px solid, text-shadow et les valeurs de box-shadow partagent la même valeur RGB — supprimer l'une d'elles casse l'illusion néon.
Trois @keyframes distincts (neonPulsePink, neonPulseCyan, neonPulseGreen) tournent à des durées différentes : 2 s, 2,5 s, 3 s. Ces périodes sont volontairement non multiples les unes des autres, ce qui garantit que les trois éléments ne pulsent jamais en phase — l'ensemble paraît organique, pas mécanique.
Pas de JavaScript, pas de requestAnimationFrame, aucune mutation du DOM. La propriété animation est ease-in-out infinite : le navigateur gère tout le timing en CSS natif. Le fond sombre (rgb(10,10,15)) est porté par .neon-glow-container — il est constitutif de l'effet ; sans fond sombre, le contraste chute et le halo disparaît visuellement.
Accessibilité
- Pas de prefers-reduced-motion : le code ne contient aucun bloc
@media (prefers-reduced-motion: reduce). L'animation pulse en continu quelles que soient les préférences de l'OS. Correctif : placer les déclarationsanimationdans@media (prefers-reduced-motion: no-preference) { … }et conserver l'état statique (valeurs 0 %/100 % des keyframes) comme valeur par défaut. - Contraste WCAG AA : les couleurs néon — rose
#ff2d95, cyan#00f0ff, vert#39ff14— sur fond#0a0a0fdépassent le ratio 4,5:1 requis pour le texte normal. Le contenu textuel reste lisible même en cas d'échec de l'animation. - Les éléments de base sont des
<div>sans sémantique interactive. Si l'effet habille des boutons ou des liens, utiliser<button>ou<a>natifs — ou a minimarole="button"+tabindex="0"+ gestionnairekeydown. - Aucun attribut ARIA dans le HTML de base : ni
role="img"niaria-labelsur le conteneur. À compléter selon le contexte d'intégration. - Effet CSS pur : aucun script ne tourne, aucun focus n'est capturé — les lecteurs d'écran lisent directement le contenu textuel des
<div>.
Compatibilité navigateur
Nécessite box-shadow multi-valeur et @keyframes CSS — supportés dans tous les navigateurs modernes depuis 2012. Zéro dépendance externe.
Sur un navigateur sans support <code>@keyframes</code> (cas rarissime), les éléments s'affichent avec leur halo statique (valeurs 0 %/100 % — faible lueur néon) — aucune erreur JS, la lisibilité est préservée.
Le code
Copiez les trois blocs dans votre page. Aucune dépendance.
<div class="chroma-demo neon-glow-container">
<div class="neon-element neon-pink">Pink</div>
<div class="neon-element neon-cyan">Cyan</div>
<div class="neon-element neon-green">Neon</div>
</div>
.chroma-demo {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
min-height: 200px;
border-radius: 8px;
overflow: hidden;
position: relative;
}
.neon-glow-container {
display: flex;
align-items: center;
justify-content: center;
gap: 20px;
background: rgb(10, 10, 15);
flex-wrap: wrap;
padding: 24px;
}
.neon-element {
padding: 12px 24px;
border-radius: 12px;
font-weight: 700;
font-size: 0.85rem;
text-transform: uppercase;
letter-spacing: 0.1em;
position: relative;
}
.neon-pink {
color: rgb(255, 45, 149);
border: 2px solid rgb(255, 45, 149);
text-shadow: rgb(255, 45, 149) 0px 0px 10px, rgb(255, 45, 149) 0px 0px 20px;
animation: 2s ease-in-out 0s infinite normal none running neonPulsePink;
}
.neon-cyan {
color: rgb(0, 240, 255);
border: 2px solid rgb(0, 240, 255);
text-shadow: rgb(0, 240, 255) 0px 0px 10px, rgb(0, 240, 255) 0px 0px 20px;
animation: 2.5s ease-in-out 0s infinite normal none running neonPulseCyan;
}
.neon-green {
color: rgb(57, 255, 20);
border: 2px solid rgb(57, 255, 20);
text-shadow: rgb(57, 255, 20) 0px 0px 10px, rgb(57, 255, 20) 0px 0px 20px;
animation: 3s ease-in-out 0s infinite normal none running neonPulseGreen;
}
@keyframes neonPulsePink {
0%, 100% {
box-shadow: rgb(255, 45, 149) 0px 0px 5px, rgb(255, 45, 149) 0px 0px 10px, rgb(255, 45, 149) 0px 0px 20px, rgba(255, 45, 149, 0.1) 0px 0px 10px inset;
}
50% {
box-shadow: rgb(255, 45, 149) 0px 0px 10px, rgb(255, 45, 149) 0px 0px 25px, rgb(255, 45, 149) 0px 0px 50px, rgb(255, 45, 149) 0px 0px 80px, rgba(255, 45, 149, 0.15) 0px 0px 20px inset;
}
}
@keyframes neonPulseCyan {
0%, 100% {
box-shadow: rgb(0, 240, 255) 0px 0px 5px, rgb(0, 240, 255) 0px 0px 10px, rgb(0, 240, 255) 0px 0px 20px, rgba(0, 240, 255, 0.1) 0px 0px 10px inset;
}
50% {
box-shadow: rgb(0, 240, 255) 0px 0px 10px, rgb(0, 240, 255) 0px 0px 25px, rgb(0, 240, 255) 0px 0px 50px, rgb(0, 240, 255) 0px 0px 80px, rgba(0, 240, 255, 0.15) 0px 0px 20px inset;
}
}
@keyframes neonPulseGreen {
0%, 100% {
box-shadow: rgb(57, 255, 20) 0px 0px 5px, rgb(57, 255, 20) 0px 0px 10px, rgb(57, 255, 20) 0px 0px 20px, rgba(57, 255, 20, 0.1) 0px 0px 10px inset;
}
50% {
box-shadow: rgb(57, 255, 20) 0px 0px 10px, rgb(57, 255, 20) 0px 0px 25px, rgb(57, 255, 20) 0px 0px 50px, rgb(57, 255, 20) 0px 0px 80px, rgba(57, 255, 20, 0.15) 0px 0px 20px inset;
}
}
// Effet CSS pur — pas de JavaScript nécessaire
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
| color / border-color / text-shadow dans .neon-pink, .neon-cyan, .neon-green | rose #ff2d95 · cyan #00f0ff · vert #39ff14 | Les trois propriétés doivent partager la même valeur RGB pour maintenir la cohérence du halo. Renommez les classes si vous préférez des identifiants sémantiques (.neon-primary, .neon-alert). |
| animation-duration dans .neon-pink / .neon-cyan / .neon-green | 2 s · 2,5 s · 3 s | Durée du cycle de pulsation par variante. Conserver des valeurs différentes pour préserver la désynchronisation — des multiples exacts (ex. 2 s / 4 s / 6 s) rephasent les éléments et cassent l'effet organique. |
| box-shadow blur 80px à 50% dans @keyframes neonPulse* | 80 px | Rayon de diffusion au pic du halo. Réduire à 40 px pour un effet contenu (composant), augmenter à 120–140 px pour une explosion lumineuse (hero plein écran). |
| padding dans .neon-element | 12px 24px | Taille physique des étiquettes. Réduire à 6px 12px pour des micro-badges, augmenter à 16px 40px pour des boutons ou titres de section. |
| font-size dans .neon-element | 0,85 rem | Taille du texte. Passer à 1,2–1,6 rem pour des titres de rubrique ; le halo s'adapte proportionnellement sans modification des keyframes. |
| gap dans .neon-glow-container | 20 px | Espacement entre les éléments. À 8 px les halos se touchent visuellement et se fondent en une bande lumineuse continue. |
| border-radius dans .neon-element | 12 px | 0 px = étiquettes carrées (style rétro terminal), 4 px = coin légèrement arrondi, 50 px = pilule — le halo suit le contour exactement. |
FAQ
L'effet fonctionne-t-il sur un fond clair ?
Techniquement oui, mais l'illusion néon disparaît : les halos box-shadow sont des couleurs additives qui nécessitent un fond sombre pour paraître lumineux. Sur fond blanc ou gris clair, les mêmes valeurs donnent un simple contour coloré sans profondeur. Intégrez le conteneur .neon-glow-container dans une section dark ou un overlay sombre.
Comment créer une quatrième variante couleur ?
Créez une classe .neon-purple avec les mêmes propriétés que .neon-pink en remplaçant la valeur RGB — par exemple rgb(168,85,247) pour du violet — dans color, border, text-shadow et les valeurs de box-shadow dans un nouveau @keyframes neonPulsePurple. Assignez une durée distincte (ex. 3,5 s) pour maintenir la désynchronisation.
Peut-on déclencher le halo au survol plutôt qu'en continu ?
Oui — retirez la déclaration animation des classes .neon-* et remplacez-la par transition: box-shadow 0.3s ease. Sur :hover, appliquez les valeurs du keyframe 50 % (halo maximal). Résultat : halo statique minimal au repos, halo plein au survol, sans aucune animation en boucle — aussi plus respectueux de prefers-reduced-motion.