Ambient Light Glow
Ambient light halo built with 4 concentric box-shadow layers animated in pure CSS — slow breathing pulse, zero JavaScript, zero dependencies.
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. Atmosphere has 57 effects, including 10 free. Explore the category →
3 usage examples



How it works
The effect stacks 4 comma-separated box-shadow values on a single element. Each layer uses the same position (0/0 offset) with increasing blur-radius — 30, 60, 100, and 150 px — and decreasing alpha: light is intense near the element and fades into the background. There is no spread-radius: only the blur diffuses light, without enlarging the source shape.
The @keyframes ambientGlow animation oscillates between two states: at keyframes 0%/100% (rest) the blurs are 30/60/100/150 px with alphas 0.5/0.3/0.2/0.1; at keyframe 50% (peak) they reach 40/80/120/200 px with alphas 0.7/0.5/0.35/0.2. The CSS engine interpolates every numeric value automatically, and the ease-in-out curve over a 3 s cycle gives the animation its organic breathing feel.
The indigo/purple hue is consistent between the element's background: linear-gradient(135deg, #6366f1, #8b5cf6) and the box-shadow RGBA values — rgb(99,102,241) maps to #6366f1 and rgb(139,92,246) to #8b5cf6. This coupling makes the halo read as light emitted by the element rather than a decorative CSS artifact.
There is no JavaScript in this effect: no requestAnimationFrame, no canvas, no DOM manipulation. All customization goes through CSS overrides on the .ambient-glow-box class and the @keyframes ambientGlow rule.
Accessibility
- prefers-reduced-motion is absent from the code. The current stylesheet contains no
@media (prefers-reduced-motion: reduce)block. In production, add.ambient-glow-box { animation: none; }inside that media query to stop the animation for motion-sensitive users. - Text contrast: the white label (
#fff) on the#6366f1→#8b5cf6gradient yields a contrast ratio of ≈ 4.8:1 — WCAG AA compliant (threshold 4.5:1). .ambient-glow-boxis a<div>with no ARIA role. If it contains functional content (not purely decorative), addrole="img"orrole="region"and a descriptivearia-label.- The element is not interactive by default: no event handlers, no keyboard trap. Tab order is unaffected.
- No JS runs: accessibility tools that inspect the DOM (NVDA, VoiceOver) are not disturbed.
Browser compatibility
Requires multi-layer box-shadow and @keyframes animation — supported in all modern browsers. Zero dependencies.
If <code>@keyframes</code> and <code>animation</code> are not supported (IE 8), the element renders with its background gradient and dimensions — no JS errors, the halo is absent but the content remains readable.
The code
HTML structure to paste into your page (CSS + JS available with a premium account):
<!-- Effect: Ambient Light Glow -->
<div class="demo-preview">
<div class="ambient-glow-box">
Your content
</div>
</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 |
|---|---|---|
| blur-radius per layer — @keyframes ambientGlow at 0%/100% | 30px / 60px / 100px / 150px | Halo reach at rest. Reduce to 20/40/60/100 px for a tight glow; raise to 40/80/140/220 px for an immersive effect on a deep-dark background. |
| blur-radius per layer — @keyframes ambientGlow at 50% | 40px / 80px / 120px / 200px | Maximum halo reach at the peak of the pulse. Layer 4 at 200 px spreads wide — fine on a black background, but reduce if the element sits near other components. |
| RGBA alpha — @keyframes ambientGlow at 0%/100% | 0.5 / 0.3 / 0.2 / 0.1 | Resting intensity. Raise to 0.7/0.5/0.3/0.15 for a strong sustained glow; lower to 0.2/0.1/0.06/0.03 for a very subtle ambient hint. |
| animation-duration — .ambient-glow-box | 3s | Duration of one full breath. 1.5 s = urgency / alert; 5–8 s = calm / ambient. |
| animation-timing-function — .ambient-glow-box | ease-in-out | linear = mechanical, uniform pulse. ease-in-out (default) = acceleration and deceleration that mimic organic breathing. |
| background — .ambient-glow-box | linear-gradient(135deg, #6366f1, #8b5cf6) | Background color of the source element. Replace with your brand color. Keep the box-shadow RGBA in sync to maintain chromatic coherence. |
| RGBA color triplets in @keyframes ambientGlow | rgb(99,102,241) = #6366f1 and rgb(139,92,246) = #8b5cf6 | Hue of each halo layer. To use a different brand palette, replace both RGB triplets consistently with the element's background. A single triplet repeated across all 4 layers gives a uniform monochrome halo. |
FAQ
.ambient-glow-box class works on any block element (div, button, a, section…) as long as it is positioned (position: relative or absolute) and has a defined size. On a button, remove browser default styles and verify that the keyboard-focus box-shadow ring does not collide with the effect's layers.background of .ambient-glow-box (gradient or solid color) and the RGBA values in @keyframes ambientGlow. The RGB triplet must match your color — for example, green #22c55e becomes rgba(34, 197, 94, .5). Changing only one of the two breaks chromatic coherence and makes the halo read as an unintentional CSS artifact.box-shadow triggers a repaint (not a reflow — it does not affect document flow when the element is positioned). The cost is low on modern browsers for isolated elements. For long lists or many simultaneous animations, prefer filter: drop-shadow(), which can be GPU-composited, or limit animation to visible elements using an IntersectionObserver.