Floating Elements
Five translucent glass shapes (a square, a circle, a pill, a small square, a tag) scattered across the whole frame each drift on their own loop, from 5.5 to 9 s, with a backdrop blur. No 3D and no interaction: flat motion, never in sync. Pure CSS, zero JavaScript, still when the user reduces motion.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. 3D has 50 effects, including 8 free. Explore the category →
3 usage examples



How it works
The .fx-0023-root root (#0a0a0f background, at least 300 px tall) holds .floating-container: full width, 250 px tall, overflow: hidden so nothing spills out. The five .floating-el shapes sit in it with position: absolute, in percentages, so they keep their layout as the frame widens: .float-1 an 80 px indigo square top left, .float-2 a 60 px pink circle at the center, .float-3 a 100 × 50 px green pill top right, .float-4 a 50 px amber square bottom left, .float-5 a 70 × 40 px violet tag bottom right. Each has a colored background at 60% opacity, backdrop-filter: blur(10px) that blurs whatever passes behind, a soft shadow and 0.75 rem white text.
Each shape has its own animation, ease-in-out, forever: floatDrift1 (6 s) moves the square up to 35 px upward while turning it from −3 to 5°; floatDrift2 (8 s) shifts the circle 25 px while swelling it from ×0.95 to ×1.05; floatDrift3 (7 s) lowers the pill 20 px and tilts it −6°; floatDrift4 (9 s) lifts the small square 30 px and turns it 10°; floatDrift5 (5.5 s) slides the tag 20 px diagonally. These are flat translations, rotations and zooms: the effect is filed under 3D but uses no perspective or depth. The different durations prevent any syncing: the overall composition only repeats after 5,544 s, over an hour and a half.
Measured in Chromium 151, Firefox 153 and WebKit 26 (no 3D, so the test engine is reliable here): same drift, blur rendered in all three, about 7% of the block's pixels changing over 0.8 s, two independent copies, 0 errors. The backdrop blur has a cost: it only shows when there is something behind (on the demo's plain background it changes nothing), and it recomputes the area under each shape every frame. Five small shapes stay light; twenty large ones over a full-page photo will be felt on a modest phone.
Accessibility
- Reduced motion: under
prefers-reduced-motion: reduce, a block scoped to.fx-0023-rootremoves the five animations: the shapes stay at their starting places. Measured in Chromium, Firefox and WebKit: 0 running animations, 0% of pixels changing over 0.8 s (7.4% without the preference). - Continuous motion: five shapes move endlessly across the frame; as the background of a reading page, provide a pause (WCAG 2.2.2) and keep the main text off the shapes, on a stable background, like the heading in the second example.
- Contrast: the 12 px white text sits on 60% colored glass: its contrast depends on what passes behind. On a dark background it stays readable; over a light photo, raise the backgrounds' opacity to 80% or darken them.
- Decorative content: if the shapes are pure decoration, put
aria-hidden="true"on the root. Screen readers announce ★ and ♥ as "black star" and "black heart": give them meaning with text nearby, like the legend in the first example.
Browser compatibility
CSS (flat transform @keyframes, backdrop-filter), zero JavaScript, no dependencies. Measured in Chromium 151, Firefox 153 and WebKit 26: same drift (0.3% difference on the still frame), backdrop blur rendered, stops under reduced motion, 0 errors. backdrop-filter is written without a prefix: Safari versions before 18, which required -webkit-backdrop-filter, show the shapes without blur; not verified on a real Safari.
Without backdrop-filter, the shapes keep their 60% colored backgrounds and their drift, with no blur behind. For older Safari, add -webkit-backdrop-filter: blur(10px) next to the existing property.
The code
HTML structure to paste into your page (the CSS + JS come with your purchase):
<div class="fx-0023-root">
<div class="floating-container">
<div class="floating-el float-1">Nav</div>
<div class="floating-el float-2">★</div>
<div class="floating-el float-3">Button</div>
<div class="floating-el float-4">♥</div>
<div class="floating-el float-5">Tag</div>
</div>
</div>
One-time payment, no subscription — the code is yours forever
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Positions (CSS — top / left / right / bottom of .float-1 to .float-5) |
percentages of the frame | Keep percentages so the layout holds at every width. Leave 35 px of margin at the edges: that is the loops' largest move, and the container clips what spills over. |
Durations (CSS — 6s, 8s, 7s, 9s, 5.5s) |
5.5 to 9 s, all different | Lengthen them all (×1.5) for a calmer background. Keep them different: equal durations would move the shapes in step and the free-drift feel would disappear. |
Amplitude (CSS — @keyframes floatDrift1 to 5) |
up to 35 px, rotations of 3 to 10° | Halve the translations for a background behind text. The circle's zoom (×0.95 to ×1.05) can go up to ×1.1 for a pulse. |
Glass (CSS — backdrop-filter and background of .floating-el) |
blur(10px), 60% backgrounds | The blur only shows when there is an image or colors behind. 4 px keeps the background recognizable; 20 px gives thick frosted glass. Add -webkit-backdrop-filter for older Safari. |
Frame height (CSS — height of .floating-container) |
250px | For a banner background, height: 100% and the root at position: absolute; inset: 0, as in the examples. |
Shapes (CSS — width, height, border-radius of each .float-n) |
80 square, 60 circle, 100 × 50 pill, 50 square, 70 × 40 tag | Widen a pill for a long word (120 px for "Bonne journée"). border-radius: 50% makes a circle, 999px a pill. |
FAQ
translate, rotate and scale, with no perspective or depth. The sense of volume comes from the glass (backdrop blur and drop shadow) and the different rhythms. For tiles that really tilt in 3D, see Floating Elements 3D (fx-0017).backdrop-filter blurs what is behind the shape. On the plain #0a0a0f background, there is nothing to blur. Set the effect over a photo or a colored background, as in the three examples, and the glass appears..float-6 and floatDrift6, on yet another duration). The blur costs something every frame over each shape's area: beyond a dozen large shapes on a phone, lower the blur or remove it from the largest ones.