Components / Motion / Liquid Button

Liquid Button beta

Hover and the button fills with liquid — a rising, rotating wave behind the label.

Preview

Hover slowly — the wave is the rotation, not a picture of one.

<div style="display:flex;gap:16px;flex-wrap:wrap;align-items:center;padding:8px 0">
  <button class="k-liq" type="button"><span class="fill" aria-hidden="true"></span><span class="lbl">Start the trial</span></button>
  <button class="k-liq dark" type="button"><span class="fill" aria-hidden="true"></span><span class="lbl">Download the mold</span></button>
</div>
<p style="font-size:12.5px;color:var(--k-ink-3);margin-top:8px">Hover slowly — the wave is the rotation, not a picture of one.</p>
/* KATA Liquid Button — hover pours. */
.k-liq{position:relative;overflow:hidden;display:inline-block;border:1.5px solid var(--k-ink);background:var(--k-bg);color:var(--k-ink);font-family:var(--k-font);font-size:14.5px;font-weight:650;padding:13px 27px;border-radius:11px;cursor:pointer}
.k-liq .fill{position:absolute;left:-30%;top:100%;width:160%;padding-top:160%;background:var(--k-accent);border-radius:42% 46% 44% 48%;transition:transform .65s cubic-bezier(.5,0,.2,1);transform:rotate(0)}
.k-liq:hover .fill,.k-liq:focus-visible .fill{transform:translateY(-58%) rotate(160deg)}
.k-liq .lbl{position:relative;z-index:1;transition:color .4s}
.k-liq:hover .lbl,.k-liq:focus-visible .lbl{color:var(--k-on-color)}
.k-liq.dark{border-color:var(--k-ink);background:var(--k-ink);color:var(--k-bg)}
.k-liq.dark .fill{background:var(--k-on-color)}
.k-liq.dark:hover .lbl,.k-liq.dark:focus-visible .lbl{color:var(--k-zinc-950)}
.k-liq:active{transform:scale(.97)}
@media (prefers-reduced-motion:reduce){.k-liq .fill{transition:none}}

Installation

CLI

node kata-ui.mjs add liquid-button

Writes the part’s CSS into your project. New to the CLI? See the CLI doc.

Manual

  1. Load tokens.css once, before any part.
  2. Copy the CSS tab into your stylesheet.
  3. Copy the HTML where it belongs.

Usage

The fill is a rotating blob on a rising carrier: hover lifts it past the label line and the rotation reads as a wave. The button stays a button — same size, same name, same keyboard behavior — with the liquid as its one party trick. Dark label on light, light label once filled; both states are token pairs, so themes keep working.

Accessibility

Fill is hover garnish: focus shows the standard focus ring, activation is unchanged, and touch users tap a perfectly good button that simply skips the pour. Under prefers-reduced-motion the fill snaps instead of rising.

Anatomy

The public surface of this part, read from its own source. Class names are the API — the CSS tab above is the full contract.

.k-liqclass
.fillclass
.lblclass
.darkclass
aria-hiddenARIA

Related parts