Neon Mesh
Four neon blobs (electric blue, hot pink, lime green, purple) drift and pulse in a loop on a dark background — animated mesh in pure CSS, zero JavaScript.
You'll get access to the interactive demo with a free account.
This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Backgrounds has 50 effects, including 6 free. Explore the category →
3 usage examples



How it works
The effect uses four <div class="neon-mesh-blob"> elements positioned with position: absolute inside the .neon-mesh container. Each blob is a perfect circle (border-radius: 50%) with a filter: blur(40px) that creates a soft halo. The container has overflow: hidden: blobs that extend outside are clipped, producing the characteristic light-edge of the mesh.
Three CSS @keyframes drive the motion: neonFloat1 (translate +30px/+20px, scale 1.15), neonFloat2 (-25px/+15px, scale 1.1), neonFloat3 (+20px/-25px, scale 1.2). Durations are deliberately asymmetric — 6s, 7s, 8s and 9s — so cycles never re-synchronise. Blob 4 replays neonFloat1 with animation-direction: reverse, giving it a motion opposite to blob 1 and adding a stirring effect.
The four colors carry different alphas: blue rgba(0,100,255,.7), pink rgba(255,0,128,.7), lime rgba(0,255,80,.6), purple rgba(180,0,255,.5). The default source-over compositing mode blends overlapping areas additively, producing intermediate hues that shift as the blobs move. The dark background #050510 absorbs uncovered light.
The optional <span class="neon-mesh-label"> floats above the blobs via position: relative; z-index: 1. Its double text-shadow — pure white at 10px then cyan-blue at 30px — simulates the glow of a neon tube. No JavaScript is involved: the effect is entirely declarative.
Accessibility
- prefers-reduced-motion: not handled in the delivered code — CSS animations always run. Add
@media (prefers-reduced-motion: reduce) { .neon-mesh-blob { animation: none } }to freeze blobs at their initial position (colors remain visible, only motion stops). - As a decorative background, the
.neon-meshcontainer should carryaria-hidden="true"— its content is purely visual and conveys no information. - The effect contains no interactive elements: no focusable zone, no keyboard event to handle.
- The
.neon-mesh-labeldisplays white text#fffon a dark background#050510— contrast ratio > 21:1, well above the WCAG AAA threshold (7:1). - Any content overlay (titles, CTA buttons) placed above the blobs is the integrator's responsibility: add a dark scrim if the contrast ratio is not guaranteed by the palette.
Browser compatibility
Requires filter: blur() and CSS animations — supported by all modern browsers since 2018.
Without <code>filter</code> support (IE 11), blobs render as solid color patches without blur — the palette remains visible, the soft gradient disappears. No JS is involved, no errors possible.
The code
HTML structure to paste into your page (CSS + JS available with a premium account):
<div class="neon-mesh" aria-hidden="true">
<div class="neon-mesh-blob"></div>
<div class="neon-mesh-blob"></div>
<div class="neon-mesh-blob"></div>
<div class="neon-mesh-blob"></div>
<!-- Optional: centered neon label -->
<span class="neon-mesh-label">Your text</span>
</div>
Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
| .neon-mesh → background | #050510 | Base background of the container. Use #000 for pure black or a linear gradient for a directional background. |
| .neon-mesh-blob → filter: blur() | blur(40px) | Blur intensity of each blob. 20px = distinct saturated patches, 80px = very diffuse halo. Scale up proportionally with container size. |
| .neon-mesh-blob:nth-child(1) → background | rgba(0,100,255,.7) | Electric blue blob color. Alpha controls intensity; lower to .4 for a subtle pastel blue. |
| .neon-mesh-blob:nth-child(2) → background | rgba(255,0,128,.7) | Hot pink blob color. Replace with rgba(255,80,0,.7) for an orange-fire tone. |
| .neon-mesh-blob:nth-child(3) → background | rgba(0,255,80,.6) | Lime green blob color. Set display:none for a simpler blue-pink duo. |
| .neon-mesh-blob:nth-child(4) → background | rgba(180,0,255,.5) | Purple blob color. Adjust alpha to tone it down without removing the hue. |
| .neon-mesh-blob:nth-child(n) → animation-duration | 6s / 7s / 8s / 9s | Asymmetric durations — do not make them equal, or cycles will sync into a visible pulse. Multiply all by 2 (12s/14s/16s/18s) for slow, contemplative motion. |
| .neon-mesh → width / height | 320px / 220px | Container dimensions. Switch to 100%/100vh for a full-screen background; increase blur proportionally. |
| .neon-mesh → border-radius | 16px | 0 for an edge-to-edge background, 50% for a circular medallion, 12px for a standard UI card. |
FAQ
@keyframes animations, filter: blur(), and absolute positioning. Zero npm dependencies, zero JS. It works in an HTML email, a sandboxed <iframe>, or a CMS with no JS access..neon-mesh these properties: position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 0 inside a position: relative; overflow: hidden section. Place your content in a child with position: relative; z-index: 1 — it will float above the blobs. Increase blur to 60–80px to soften the effect at full scale.@media (prefers-reduced-motion: reduce) { .neon-mesh-blob { animation: none } } to freeze blobs at their initial position. Colors remain visible; only motion stops.