Any content
Icons, logos, images, buttons, links, headings. If it renders, it can fill. Bring your own icon set.
v0.1.1 React · MIT · 2.7 kB
react-liquid-fill is a tiny React component and hook that reveals icons, buttons and text with an animated liquid edge. On hover, on focus, or as they scroll into view.
npm i react-liquid-fillHover any logo
Works with the icons you already use
Features
Icons, logos, images, buttons, links, headings. If it renders, it can fill. Bring your own icon set.
Hover, keyboard focus, scrolling into view, or your own code. Mix them, or scrub progress with setProgress().
One component, one hook and one pure function. No dependencies, no stylesheet, no provider.
Focus triggers the fill, the duplicate layer is hidden from screen readers, and reduced-motion users see an instant change.
Safe to server-render. Works in the App and Pages Router, Vite, Remix and any React 18+ setup.
Written in TypeScript with documented options, so your editor completes every prop.
Playground
Every control maps to a prop. The snippet updates as you change them.
Move your pointer over it from different sides
<LiquidFill
direction="auto"
duration={{ in: 460, out: 340 }}
wave={{ amplitude: 0.3 }}
base={<img src="/angular-outline.svg" alt="" />}
fill={<img src="/angular.svg" alt="" />}
/>Use cases
Portfolio and agency pages that list the tools behind the work. Outline at rest, brand colour on hover.
Buttons that invert as the pointer arrives, from whichever side it came. Tap to toggle on touch screens.
Menus where each item fills as you move along them, and keyboard users get the same effect on focus.
Get started
Give LiquidFill a base and a fill. Hover and keyboard focus work immediately.
import { LiquidFill } from "react-liquid-fill";
export function Logo() {
return (
<LiquidFill
base={<img src="/logo-outline.svg" alt="" width={48} height={48} />}
fill={<img src="/logo.svg" alt="" width={48} height={48} />}
aria-label="Acme"
role="img"
/>
);
}FAQ
It stacks two versions of an element, such as an outlined and a full-colour icon, and reveals the top one with an animated liquid edge when the user hovers, focuses or scrolls to it.
Yes. It doesn't ship icons. Pass any two renderings as base and fill: image files, SVG components from react-icons or Lucide, emoji or text.
About 2.7 kB minified and gzipped, with no dependencies besides React.
Yes. Set trigger="inView" to fill as elements scroll into view, or call setProgress() to tie the fill to scroll position.
Keyboard focus triggers the same effect as hover, the fill layer is aria-hidden so content is announced once, and users who prefer reduced motion get an instant change.
Installation, live demos, guides for every icon set and the full API.
Discover the core library