Gooey menu

구이 메뉴

A floating action button whose sub-items bud off like droplets when it opens — items start fused to the main button as one blob, then smoothly pinch apart as they spread.

Also known as: Blob FAB menuLiquid radial menu
···
html
<svg width="0" height="0"><defs><filter id="goo2"><feGaussianBlur in="SourceGraphic" stdDeviation="8" result="b"/><feColorMatrix in="b" mode="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 26 -12"/></filter></defs></svg>
<div class="gstage">
  <div class="gwrap" id="gwrap">
    <i class="item it1"></i><i class="item it2"></i><i class="item it3"></i><i class="item it4"></i>
    <div class="main"></div>
  </div>
  <span class="icon">+</span>
</div>
css
.gstage{position:relative;width:100%;height:100%;display:grid;place-items:center}
.gwrap{position:relative;filter:url(#goo2);width:1px;height:1px}
.main{position:absolute;top:0;left:0;width:44px;height:44px;margin:-22px 0 0 -22px;border-radius:50%;background:var(--accent)}
.item{position:absolute;top:0;left:0;width:30px;height:30px;margin:-15px 0 0 -15px;border-radius:50%;background:var(--accent-2);
  animation:pop 2.8s ease-in-out infinite}
.it1{animation-delay:0s}.it2{animation-delay:.05s}.it3{animation-delay:.1s}.it4{animation-delay:.15s}
.icon{position:absolute;color:#fff;font:800 20px/1 sans-serif;pointer-events:none}
@keyframes pop{
  0%,14%{transform:translate(0,0) scale(.6)}
  45%,72%{transform:translate(var(--tx),var(--ty)) scale(.82)}
  100%{transform:translate(0,0) scale(.6)}
}
.it1{--tx:-58px;--ty:-14px}
.it2{--tx:-24px;--ty:-52px}
.it3{--tx:24px;--ty:-52px}
.it4{--tx:58px;--ty:-14px}

The same SVG gooey filter (feGaussianBlur + feColorMatrix) from liquid button applies to the whole menu. The difference is that instead of one circle, the filter group holds the main button plus one circle per sub-item — while closed, every sub-item sits at the same position as the main button (distance 0), so the filter melds them into one blob; the moment the menu opens, each item translates out to its own target angle and distance, and as that distance grows the gooey "bridge" effect fades away, reading as droplets pinching off naturally.

Each item's target position comes from a semicircular or full-circle layout — item i's angle is (total spread angle / (item count − 1)) × i, and its position is translate(cos(angle) × radius, sin(angle) × radius). Shrinking scale slightly (around 0.9) as it moves away from the main button reinforces the sense of "a droplet that just formed."

Text can render blurry inside a gooey-filtered region, so icons and labels usually sit on a separate layer outside the filter group, stacked on top of the filtered background shapes with z-index.

When to use

Use it for short menus — three to five items — on a mobile FAB, when you want a branded opening flourish. Not a fit for menus with many items (six or more) or long text labels — the gooey filter's blur hurts readability.