Glossy cherry-red letters on a butter-yellow wall sag and drip, drops fall and ring a pool on the ledge below, softbox highlights sliding down every neck and bulb, then surface tension pulls the liquid back up into crisp enamel letterforms.
Written and rendered by AI CSS Animations Oct 18, 2026
Dripping letters have been a poster and comic device for decades, from horror film titles to candy and soda advertising. In motion design, glossy liquid type is usually built with fluid simulation or metaball surfaces, and its realism comes from how liquid behaves: drips that neck and thin as they lengthen, a round bead at every tip, a meniscus where liquid meets a surface and highlights that slide along the gloss. Food, beverage, cosmetics and music brands use it for anything that should feel rich, wet or indulgent.
Make a 10-second glossy liquid type piece: thick cherry-red letters sag, drip and pool on a ledge, then the liquid pulls back up into crisp letterforms. <inputs> If I don't give you something, use the default and don't ask. - Word: GLAZE - Brand line: Glaze Enamel Paint (fictional) · Shade 07, Cherry - Tagline: "One coat. Full gloss." - Length: 10 seconds. </inputs> <direction> - Palette: wall butter #F6E6A8, lifting to #FBF1CC behind the word; ledge top #EDD486; ledge front #DDBF62 with a 1px lighter lip #F8E7A8; liquid cherry #C8102E, deep #7A0A1C where it gathers thick, thin edges #E2283F, specular white #FFFFFF, a pink sheen #FF9AA2 at grazing angles; small type #5A1A12. - Type: "Bagel Fat One" 400, uppercase, about 400px, the word centered on x 960 with its baseline at y 600, about 1300px wide; small type in "Sora". - The liquid is one 2D distance field, shaded as a glossy raised surface in a WebGL fragment shader: - At load, draw the word white on black on an offscreen canvas and compute its signed distance field with a two-pass Euclidean distance transform; upload it as a float texture. - Each frame the shader joins, with a smooth minimum (k about 24px, so joins neck and bulge like syrup): the letters, sampled through a sag warp; the drips, vertical capsules ending in a round bulb 1.3× the neck's radius; falling drops, circles; and the pool, a flattened capsule lying on the ledge. - Height from distance: inside the shape, h = R·sqrt(1 − (1 − min(d/R, 1))²) with R = 26px, a rounded bead along every edge and a flat top across wide strokes. Take normals from the height field. Shade with two soft rectangular softbox reflections from the upper left (a lookup on the reflected vector), a tight specular (Blinn power 140), Fresnel toward the pink sheen at the rims, and color by thickness: lighter where thin, deep where liquid gathers. Under it all, a soft contact shadow on the wall (the field blurred, 10px down, 16% opacity) and a darker wet line where the pool meets the ledge. - Melt, computed from t, never stepped: the sag warp samples the letters at (x, y − s(t)·smoothstep(y_mid, y_base, y)), lowering their lower halves by up to 40px. Nine drips leave the feet of stems and the bottoms of bowls at seeded x positions; each grows as L·(1 − e^(−(t − t₀)/τ)), with L 90–250px and τ 0.6–1.1 s, its neck thinning as it lengthens; the longest reach the ledge and feed the pool. Two drips each release a drop that falls as ½·g·(t − t₁)² (g = 2600 px/s²), lands in the pool and throws two concentric highlight rings that spread and fade over 0.5 s. The pool spreads along the ledge under the word. - Reverse: from 6.6 s, surface tension wins: the drips retract upward (easeInOutCubic, 1.0 s), the pool draws back up through them, the sag springs back and the corners sharpen as the smooth-minimum radius falls from 24px to 3px, until the word stands crisp and glossy, like enamel letters with clean edges and no trace of paint. - Layout: the ledge top runs across the frame at y 860, the ledge front from 860 down. Brand line in Sora 500, 26px, tracked 0.14em, uppercase, centered on baseline y 190; tagline in Sora 600, 38px, centered on the ledge front at y 970. - Motion is viscous: things accelerate slowly and stretch; nothing snaps except the final crisp-up. Premium: gloss that tracks the surface, necks that thin, a bulb at every drip tip, a pool with a meniscus. Cheap: a red font with a drip brush and a gradient. Banned: chrome or metallic liquid, rainbow, bloom, blur, noise that boils on the surface, flat red with no highlights, drips that run upward before the reverse, drops that stop in midair, particle splashes, anything flashing more than 3 times per second. </direction> <structure> - 0.0–0.8s: the word stands glossy and still on the butter wall, softbox highlights resting on its tops. - 0.8–2.6s: the brand line fades up; the letters warm and sag, their lower halves slumping and their edges rounding; the first four drips bead at the feet of G, L, A and Z and begin to run. - 2.6–4.6s: the other drips start; the long ones reach the ledge and feed a growing pool; the first drop falls at 3.4 s and rings the pool; highlights slide down the drips as they stretch. - 4.6–6.6s: the melt at its fullest, still creeping: drips ease toward their final lengths, the second drop falls at 5.2 s, the pool's meniscus glints. The word still reads across its upper halves; the 6 s frame is the richest of the piece. - 6.6–7.8s: the reverse: drips and pool pull back up into the letters, the sag recovers, the corners sharpen. - 7.8–8.6s: the word stands crisp and glossy; the tagline rises 12px as it fades in on the ledge front. - 8.6–10.0s: hold, perfectly still. For other lengths, stretch the 4.6–6.6s beat; keep at least 1 s of hold. </structure> <build> - One self-contained index.html (inline CSS and JS), a 1920×1080 (16:9) stage scaled to fit the window, designed for 60fps. No image, video, texture or model files: every shape and texture is generated in code. - window.seek(t), t in seconds, computes every visual from t alone: no CSS transitions or CSS animations, no setTimeout/setInterval, no state carried between frames, randomness only from a seeded PRNG. Anything cumulative is solved analytically from t or precomputed once at load at a fixed step. Past the end, seek clamps to the last frame. - Without ?render in the URL, drive seek from requestAnimationFrame so it plays in a browser (loop after a 1s end hold); with ?render, don't start that loop. - Google Fonts via <link> are fine; await document.fonts.load() for each face before building the distance field and defining window.seek. - Engine: Canvas: one WebGL canvas (preserveDrawingBuffer: true, drawn once per seek), the backing store sized from CSS size × devicePixelRatio, with the distance field built on an offscreen 2D canvas at load. Small type is HTML over the canvas. No libraries (no three.js). - Drip, drop, pool and sag parameters are uniforms computed in closed form from t each seek. </build> <check> Before showing me, step through one frame per second (t = 0…10): screenshot each and look at it. Fix overlaps, clipped or cramped text, and anything off-style or Banned. Check every drip has a bulb and a thinning neck, highlights follow the surface rather than sitting flat, drops fall and land rather than pop, the word reads across its upper halves at 6 s, and the final letters are crisp with no leftover drips or pool. Confirm seek(10) and seek(11) match, so the final frame holds. </check>
Ours, and free to use under CC0: copy it, change it, ship it. No credit needed.
A slow, ribbon-like gradient mesh flows in a skewed band behind sharp headline type, while white payment, API and chart…
A jazz-tempo film title sequence in flat vermilion, mustard, bone and black: hand-cut paper shards jab in on the beat,…
A mechanical station departure board where every flap steps through its drum to land on times, destinations and statuse…
A Swiss-style event poster that builds itself on a visible 12-column grid: grotesque type rises out of baseline masks,…
More like this on the motion design inspiration board: Kinetic typography inspiration