Light Leak
Three oversized CSS-animated gradients fuse through mix-blend-mode screen to mimic analog film light leaks — without a single line of 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. Atmosphere has 57 effects, including 10 free. Explore the category →
3 usage examples



How it works
The effect is 100% CSS: no JavaScript, no canvas. Three <div> elements (.lightleak-a, .lightleak-b, .lightleak-c) are stacked inside a .lightleak-overlay that carries mix-blend-mode: screen. This blend mode adds RGB channels: overlapping orange and pink produces warm white; overlapping two dark areas stays dark — exactly the behavior of a light leak on analog film.
Each div is deliberately oversized (150%, 120%, 80×200% of its container) and positioned to overflow. The overflow: hidden on .lightleak-container clips it — only the portion that enters the frame is visible, creating the illusion of an off-screen light source sliding across the scene.
Three independent @keyframes animations drive the movement: leakDrift1 (7 s), leakDrift2 (9 s), leakDrift3 (6 s). Their durations are mutually coprime (GCD = 1 s, LCM = 63 s) — the three never align simultaneously before 63 seconds, making the motion feel organic. Each keyframe combines translate, rotate (±3–5°), and opacity to mimic camera shake and the exposure variation of a physical film.
The gradients have different geometries: .lightleak-a uses a radial-gradient anchored at 30%/50% (orange→yellow), .lightleak-b a radial-gradient at 70%/30% (pink→purple), and .lightleak-c a linear-gradient at 135° on a portrait-oriented 80×200% div (golden amber). The three layers combined produce the overexposure zones characteristic of the film look.
Accessibility
- prefers-reduced-motion absent: the code contains no
@media (prefers-reduced-motion: reduce)block — animations run regardless of system preference. Add it manually if needed (see FAQ). - The
.lightleak-overlaydoes not carryaria-hiddenin the provided code — add it if the effect is purely decorative, so screen readers don't needlessly traverse the empty divs. - The effect has no keyboard interaction and exposes no focusable element — no focus trap or tab order issue.
- Text contrast depends entirely on the content you place inside
.lightleak-content-bg; the screen-blended leaks can locally brighten the background and reduce contrast — verify WCAG AA (4.5:1) with your final text. - No seizure risk (WCAG 2.3.1): all animations use smooth
ease-in-outtransitions and the long durations (6–9 s) produce no flashes.
Browser compatibility
Requires CSS mix-blend-mode and @keyframes animations — supported in all modern browsers since 2016.
On IE 11 (not officially supported), <code>mix-blend-mode</code> is ignored — the leak divs render opaque over the background without blending. The page stays functional. All modern browsers render identically.
The code
HTML structure to paste into your page (CSS + JS available with a premium account):
<div class="lightleak-container">
<!-- Background + text content: lower z-index than the overlay -->
<div class="lightleak-content-bg">
<span>Your content</span>
</div>
<!-- Light leak overlay: mix-blend-mode screen -->
<div class="lightleak-overlay">
<div class="lightleak-a"></div>
<div class="lightleak-b"></div>
<div class="lightleak-c"></div>
</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 |
|---|---|---|
| .lightleak-a colors (CSS radial-gradient line) | rgba(255,100,50,.3) → rgba(255,200,50,.15) | Tint of the first gradient (orange→yellow range). Change RGB values for a teal, violet, or brand-matched look. |
| .lightleak-b colors (CSS radial-gradient line) | rgba(255,50,100,.25) → rgba(200,100,255,.1) | Tint of the second gradient (pink→purple). Reducing opacity to 0.08 removes the pink for a purely warm look. |
| .lightleak-c colors (CSS linear-gradient line) | rgba(255,200,100,.15) → rgba(255,150,50,.2) → rgba(255,200,100,.1) | Tint of the diagonal light rail. Change the angle (135deg) to redirect the flare across the scene. |
| Animation durations (animation property) | 7s / 9s / 6s (leakDrift1/2/3) | Shorter durations (3–5 s) give a more nervous movement; longer (12–18 s) produce a very slow cinematic drift. |
| @keyframes leakDrift1 translate amplitudes | translate(30px, -20px) rotate(5deg) | Larger px values widen the leak's sweep across the scene; reducing to 10 px / 0 deg gives an almost static pulsation. |
| @keyframes leakDrift2 translate amplitudes | translate(-20px,15px) / translate(15px,-10px) | leakDrift2 has 3 steps — its more complex motion creates the organic beat against leakDrift1. |
| .lightleak-container background | #1a1a2e | The dark background maximises gradient contrast in screen mode. Switch to #0a0a0f for a deeper cinema black; a tinted background colors the entire composition. |
| .lightleak-a / .lightleak-b / .lightleak-c size (width/height) | 150%/150% · 120%/120% · 80%/200% | Reducing to 80% localises the leak; increasing to 200% pushes it further off-screen for a very diffuse light source. |
FAQ
@media (prefers-reduced-motion: reduce) { .lightleak-a, .lightleak-b, .lightleak-c { animation: none; opacity: 0.4; } }. The leaks remain visible in a fixed static state — the ambience is preserved without causing discomfort to motion-sensitive users..lightleak-content-bg (already in the HTML, at a lower z-index than the overlay) or add an element with position: relative; z-index: 3 above .lightleak-overlay (z-index 2). Check WCAG AA contrast: the brightest screen-blended zones can add +20–30% luminosity to the background, which may require a text-shadow or a semi-transparent scrim behind the text.lightleak-* classes under a parent selector if your global styles conflict. In a Shadow DOM or CSS Module, simply rename the classes consistently throughout.