151

Gooey Liquid Nav

£7 or the whole Vault, £79.20

A navigation bar whose active indicator is one body of glossy liquid. It stretches, necks and splits between items, sheds a satellite droplet, reaches towards the item you hover, and drips into a liquid rule at the foot of the nav when it arrives hard.

advanced
6 more details
webgl-shadermetaballssliding-indicator-tabsmicro-interactionkeyboard-navigationprogressive-enhancement

This demo reads better at your own screen size than in the frame below:

About this effect

Gooey Liquid Nav is the navigation bar you drop into a header or an app, with one difference: the indicator under the current item is a body of thick, glossy liquid, like syrup or wet paint. It has a real surface. A highlight and a soft darker rim follow its curves as it moves, and it casts a soft shadow on the page.

Read the full effect overview

Click another item and the liquid reaches for it. Next door, it stretches across and settles with a small wobble. Further away, it pulls out a neck that thins and pinches in two: the leading mass arrives first, the tail catches up and merges, and a small satellite droplet that broke off at the back rolls in last. Click again mid-flight and it changes course without leaving stray blobs behind. Hover or keyboard-focus another item and a short tendril reaches towards it, then withdraws when you move away.

When the liquid arrives hard, a drip forms on its underside, hangs on a thinning neck, lets go and falls into the liquid rule at the foot of the nav, where it spreads into a shallow puddle, sends out a ripple and is slowly drawn back in.

The labels are real links and stay sharp and exact. Their colour switches from ink to white precisely where the liquid covers them, pixel for pixel, including while the liquid is passing through a word.

Gooey Liquid Nav - GSAP animation effect preview

What's included

11 items
  • One body of lit liquid as the active indicator, with highlight, darker rim and soft contact shadow
  • Stretches to near items; necks, splits and re-merges on long jumps, with a trailing satellite droplet
  • Hard arrivals drip into a liquid rule that puddles, ripples and draws the drop back in
  • A short tendril reaches towards the hovered or focused item
  • Label colour switches exactly where the liquid covers it, mid-word included
  • Retargets cleanly when clicked again mid-flight
  • Real links or tab buttons; arrow keys, Home and End move between items
  • Reduced motion keeps the liquid look but slides it as one pill, with no stretch, drips or ripples
  • Without JavaScript or WebGL, a solid indicator on the current item
  • Colours and gloss by CSS custom properties; viscosity and drips by data attributes
  • Small API to set the item, re-measure and revert cleanly; a change event for your router

Perfect for

4 use cases
  • The main navigation of a food, drinks, cosmetics or paint brand site
  • Section tabs in an app or dashboard header
  • A single-page site whose nav tracks the section in view
  • Category tabs above a shop grid

How it works

3 sections

The liquid is drawn on a canvas laid over the nav, by a shader that treats the indicator as a handful of soft shapes which pull into each other as they get close, the way drops of water do. From the shape of that surface it works out which way each point faces and lights it, so the highlight, the darker rim and the shadow follow the liquid as it changes shape.

The movement is simulated rather than tweened. The front of the liquid heads for the new item quickly, the back follows more slowly and a last droplet slower still, so the body stretches, thins and breaks on long runs and joins up again as it settles. Viscosity sets how much it lags and how long it hangs on before it breaks. A hard arrival starts a drip, which falls under gravity into the rule below and becomes a spreading puddle.

The labels underneath are the real links. The canvas paints a matching copy of the label text in the on-liquid colour wherever the liquid covers it, so the colour changes in the same frame and on the same pixel as the liquid. GSAP runs the frame clock, switches to the calm version under reduced motion and tears everything down; the canvas pauses when the nav is off screen or the tab is hidden.

Difficulty Advanced
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Lighthouse, as measured

Google Lighthouse on this effect's demo, from the latest scan. A measurement of the demo as shipped, not a promise for your page.

Accessibility
100
Best practices
100

No performance score, on purpose. That figure depends on how you deploy: your server's compression and caching, your CDN, the connection and the device doing the test, none of which the code controls. The same page can score very differently on two consecutive runs, so measure it where it will live.

Paid effect

Purchase to unlock the code.

Buying Gooey Liquid Nav opens the HTML, CSS and JavaScript source, the full documentation, an AI setup prompt for your editor, and every update we ship to it. Standard license: unlimited personal and commercial projects. Every paid product is tested for desktop and mobile layouts, reduced-motion handling, animation cleanup and keyboard controls wherever there is something to operate.

£7 Standard license, unlimited projects

Browse free effects

Or the whole library: the Vault, £79.20, one payment.

Documentation

Quick Start

1. Add to your HTML <head>:

Code snippet omitted: it ships with the download.

2. Add before the closing </body> tag:

Code snippet omitted: it ships with the download.

3. Mark up your nav:

Code snippet omitted: it ships with the download.

Every [data-goo] on the page is mounted automatically.

Using It With Your Own Design

What the effect needs from your markup:

  • A root with data-goo, and items with data-goo-item. Items can be links (<a>, marked aria-current="page" when current) or tab buttons (role="tab", marked aria-selected="true"). The script keeps those attributes up to date as the indicator moves.
  • The liquid takes the size of each item's box. Give items a height, horizontal padding and border-radius: 999px, and the liquid is that pill. The bar is horizontal: items should sit in one row.
  • Item text is the label. If an item holds an icon as well, wrap the text in data-goo-label; only text changes colour on the liquid.
  • data-goo-pool is the rule at the foot of the nav. Its position, width and height are read from your CSS; drips fall from the indicator to it, so the gap between them is the length of the fall.

What the stylesheet must keep: Part 1 of style.css. It gives the root position: relative and isolation: isolate, places the canvas above the labels, draws the focus ring above the canvas, and holds the fallback styling. The canvas reaches about 40px beyond the items so wobbles and tendrils are never cut off flat: don't put overflow: hidden on the nav itself, and if that adds a horizontal scrollbar at a page edge, put overflow: clip on a wrapper as the demo does on .stage.

Fallback: without JavaScript or WebGL the current item gets a solid --goo-fill pill with --goo-label-on text and the pool is a flat coloured rule. Restyle those in Part 1 if you change the look. While the liquid is running the script adds is-live to the root.

Labels: put the label colour on --goo-label, not on color, so the live and fallback states agree. The colour on the liquid is drawn by the canvas from a copy of your label text in the same font, so any web font works; it redraws when fonts finish loading. If your labels change after load, call refresh().

Multi-page sites: a link navigates straight away, so the next page simply shows the indicator at rest on its current item. The motion shows on single-page sites, tabs and in-page section navs, or wherever you delay navigation yourself.

What is only the demo's styling: the stage, the Unbounded and Inter faces, the raspberry and ink palette and the spacing.

Custom property Default Description
--goo-fill #d1145a Liquid colour (any CSS colour)
--goo-label #141412 Label colour off the liquid
--goo-label-on #ffffff Label colour where the liquid covers it
--goo-shine 1 Gloss: 0 reads as flat paint, 1 as wet syrup
--goo-focus #141412 Keyboard focus ring colour

Check contrast of --goo-label-on against --goo-fill (4.5:1 for normal text). The default pair is 5.3:1.

Options

Attribute Default Description
data-goo-viscosity 0.5 0 to 1. Higher lags more, hangs on longer before it breaks, and drips more slowly
data-goo-drips on off stops drips (the pool rule still shows if present)
data-goo-active none Index of the item to start on, overriding aria-current / aria-selected

Accessibility

  • Items stay native links or tab buttons, so screen readers, Tab order and Enter work as usual. aria-current or aria-selected always names the current item.
  • Arrow keys, Home and End move focus between items; tabs also activate on focus.
  • The keyboard focus ring is drawn above the liquid.
  • The canvas is aria-hidden and ignores the pointer.
  • Under prefers-reduced-motion: reduce the liquid slides as one rigid pill: no stretch, no tendril, no drips, no ripples. A preference change while the page is open switches over live.
  • Without JavaScript or WebGL a plain solid indicator marks the current item.

Dependencies

Required:

  • GSAP 3.12+ (the demo is pinned to 3.15.0). No plugins. GSAP runs the frame clock, the reduced-motion switch and teardown; the liquid's motion is a spring simulation in script.js, and the drawing is a WebGL shader with no other library.

Browser Support

Current Chrome, Edge, Firefox and Safari with WebGL. Browsers without WebGL get the fallback indicator.

Performance

The canvas covers only the nav and its pool, redraws only while the liquid is moving, and stops while the nav is off screen or the tab is hidden. The pixel ratio is capped at 2 (1.5 on touch screens). If a low-end device struggles, lower that cap first, or set data-goo-drips="off".

Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.