AI CSS Animations

Radial Menu Hover Effect

A round button that swirls six actions out into a ring around itself on hover. Each item is rotated, pushed out and rotated back, so the icons stay upright while they spiral into place.

Also known as: circular menu css, pie menu on hover, radial speed dial.

HTML

<nav class="hfx-radial-menu" aria-label="Quick actions">
  <button class="hfx-radial-menu-toggle" aria-label="Show actions"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg></button>
  <a href="#" aria-label="Like" style="--i: 0"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 20s-7.5-4.6-7.5-10A4.3 4.3 0 0 1 12 7.2 4.3 4.3 0 0 1 19.5 10c0 5.4-7.5 10-7.5 10z"/></svg></a>
  <a href="#" aria-label="Share" style="--i: 1"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3v12M7.5 7.5 12 3l4.5 4.5M5 13v5.5A1.5 1.5 0 0 0 6.5 20h11a1.5 1.5 0 0 0 1.5-1.5V13"/></svg></a>
  <a href="#" aria-label="Save" style="--i: 2"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6.5 4h11v16.5L12 16.5l-5.5 4z"/></svg></a>
  <a href="#" aria-label="Copy link" style="--i: 3"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 14a4.5 4.5 0 0 0 6.4 0l3-3a4.5 4.5 0 0 0-6.4-6.4l-1 1"/><path d="M14 10a4.5 4.5 0 0 0-6.4 0l-3 3a4.5 4.5 0 0 0 6.4 6.4l1-1"/></svg></a>
  <a href="#" aria-label="Email" style="--i: 4"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="5" width="18" height="14" rx="2.5"/><path d="m3.5 7 8.5 6 8.5-6"/></svg></a>
  <a href="#" aria-label="Comment" style="--i: 5"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 11.5a7.5 7.5 0 0 1-10.9 6.7L4 19.5l1.3-4.6A7.5 7.5 0 1 1 20 11.5z"/></svg></a>
</nav>

CSS

.hfx-radial-menu {
  --c: var(--hfx-color, #3b82f6);
  font-size: var(--hfx-size, 16px);
  position: relative;
  display: grid;
  place-items: center;
  width: 3.2em;
  height: 3.2em;
}
/* an invisible disc that keeps the hover alive between the items */
.hfx-radial-menu::before {
  content: "";
  position: absolute;
  inset: -4.2em;
  border-radius: 50%;
  transform: scale(0);
}
.hfx-radial-menu:is(:hover, :focus-within)::before { transform: scale(1); }
.hfx-radial-menu-toggle {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 3.2em;
  height: 3.2em;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--c);
  box-shadow: 0 0.5em 1em -0.4em color-mix(in srgb, var(--c) 80%, transparent);
  color: #fff;
  cursor: pointer;
  transition: transform 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.hfx-radial-menu-toggle svg { width: 1.4em; height: 1.4em; }
.hfx-radial-menu a {
  --a: calc(var(--i) * 60deg);
  position: absolute;
  top: 50%;
  left: 50%;
  display: grid;
  place-items: center;
  width: 2.3em;
  height: 2.3em;
  margin: -1.15em 0 0 -1.15em;
  border: 1px solid color-mix(in srgb, var(--c) 35%, transparent);
  border-radius: 50%;
  background: color-mix(in srgb, var(--c) 12%, transparent);
  color: var(--c);
  opacity: 0;
  transform: rotate(calc(var(--a) - 90deg)) translateY(0) rotate(calc(90deg - var(--a))) scale(0.4);
  transition: transform 0.5s cubic-bezier(0.34, 1.4, 0.64, 1), opacity 0.2s ease, background-color 0.2s ease, color 0.2s ease, scale 0.2s ease;
  transition-delay: calc(var(--i) * 30ms);
}
.hfx-radial-menu a svg { width: 1.1em; height: 1.1em; }
.hfx-radial-menu:is(:hover, :focus-within) .hfx-radial-menu-toggle { transform: rotate(135deg); }
.hfx-radial-menu:is(:hover, :focus-within) a {
  opacity: 1;
  transform: rotate(var(--a)) translateY(-4.3em) rotate(calc(-1 * var(--a))) scale(1);
}
.hfx-radial-menu a:is(:hover, :focus-visible) {
  background: var(--c);
  color: #fff;
  scale: 1.12;
  transition-delay: 0s;
}

@media (prefers-reduced-motion: reduce) {
  .hfx-radial-menu, .hfx-radial-menu *, .hfx-radial-menu::before, .hfx-radial-menu::after, .hfx-radial-menu *::before, .hfx-radial-menu *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Customizing this snippet

  • Color: set --hfx-color on the element or a parent. Currently previewing #3b82f6.
  • Base size: set --hfx-size. Every other dimension is in em, so the whole thing scales together. Currently previewing 16px.
  • Speed: change the duration on the transition or animation shorthand. Staggered delays are relative, so they keep their rhythm.
  • Reduced motion: the rule at the end of the CSS turns the motion off for people who asked their OS for less of it. Keep it.

Similar hover effects

Sliding Pill Nav Hover Effect
Directional Underline Nav Hover Effect
Dot Indicator Nav Hover Effect
Vertical Nav Indicator Hover Effect