webdevpuneet.com

Radial Menu — Free HTML CSS JS Fan-Out Action Snippet

Radial Menu · Navigation · Plain HTML, CSS & JS · Live preview

CategoryNavigation

Copy & paste

Source Code

<div class="rm-stage">
  <div class="rm-menu" id="rmMenu">
    <button class="rm-trigger" id="rmTrigger" aria-haspopup="true" aria-expanded="false" aria-label="Open actions">+</button>
  </div>
  <p class="rm-hint">Click the button to fan out actions</p>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Trig arc placement
Polar-to-Cartesian spaces items evenly.
Configurable fan
START, SPREAD, and RADIUS shape the arc.
Spring motion
An overshooting easing pops items out.
Staggered cascade
Per-item delays unfurl the menu.
Rotating trigger
Plus turns to a close icon on open.
Hover labels
Tooltips name the icon-only actions.
Click-away and Escape
Standard dismissal.
Accessible trigger
aria-haspopup and aria-expanded.

About this UI Snippet

Radial Menu — Actions That Fan Out on an Arc

Screenshot of the Radial Menu snippet rendered live

The radial menu is the playful action launcher where tapping a central button makes its options spring outward along a circular arc, each landing at an evenly-spaced position around the trigger. It is compact at rest and delightful in motion. This snippet builds it with plain HTML, CSS, and vanilla JavaScript that places the items with a little trigonometry.

Positioning items on an arc

Each action button starts stacked exactly on the trigger and has a precomputed resting position on the arc. For item i, the angle is START + (SPREAD / (count - 1)) * i, converted to radians, and the offset is (cos(angle) * RADIUS, sin(angle) * RADIUS). That standard polar-to-Cartesian conversion spreads the items evenly across a 180° arc at a fixed radius from the center. Because the angles are computed from constants, you change the fan shape — full circle, quarter arc, different radius — just by editing START, SPREAD, and RADIUS.

The spring open and close

Opening toggles an .open class and, for each item, sets a transform to its arc offset at full scale; closing returns every item to translate(0,0) scale(.2) stacked under the trigger. The transition uses an overshooting cubic-bezier(.34, 1.4, .5, 1), so the items spring past their target and settle — the bouncy pop that makes a radial menu feel alive rather than mechanical. The trigger itself rotates the + to a × (135°) on open as a clear affordance.

Staggered emergence

Rather than all items appearing at once, each gets a transition-delay proportional to its index on open (and reversed on close), so they fan out one after another and fold back in sequence. This small cascade reads as the menu unfurling and is the difference between a cheap reveal and a satisfying one.

Hover labels

Each item shows a tooltip label on hover via a small .rm-label that fades in beneath it, so the icon-only buttons remain understandable. The items only become interactive (pointer-events: auto) when the menu is open, so the collapsed stack does not intercept clicks.

Dismissal and accessibility

The menu closes on a click anywhere else (the trigger stops propagation so opening does not immediately self-close) and on Escape. The trigger carries aria-haspopup and an aria-expanded that flips with state, and items are real <button>s, so the control is keyboard- and screen-reader-aware. Wire each item click to its action by reading from the ACTIONS data.

Customizing it

Edit the ACTIONS array to change the options, adjust START/SPREAD/RADIUS to reshape the fan (set SPREAD to 360 for a full ring), retune the spring and stagger, or recolor the trigger and items. Anchor the menu in a corner with a quarter-circle arc for a floating action button. Pair it with a gooey menu or an expanding fab for related launcher patterns.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA single round trigger button renders.
  2. 2
    Click the triggerAction items spring out along a half-circle arc.
  3. 3
    Watch the staggerItems fan out one after another with a bounce.
  4. 4
    Hover an itemA tooltip label names the action.
  5. 5
    Dismiss itClick elsewhere or press Escape to fold it back.
  6. 6
    Reshape the fanEdit START, SPREAD, and RADIUS constants.

Real-world uses

Common Use Cases

Floating action buttons
Offer a radial take on an expanding FAB, with options springing outward along a circular arc.
Quick action launchers
Fan out edit, share and delete from a central trigger, with START, SPREAD and RADIUS constants shaping the arc.
Canvas and editor tools
Pair with a context menu for right-click operations in canvas and editor tools, using trigonometry to space items evenly around the arc.
Mobile launchers
Offer mobile apps a playful cousin of a gooey menu, with staggered per-item delays that unfurl the whole menu smoothly.
Map and media controls
Surface controls around a focal point, using an overshooting easing so each item pops out with a spring.
Related: Sticky Product Bar
See the Sticky Product Bar for a related navigation pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

Each item gets an angle of START + (SPREAD / (count - 1)) * index, converted to radians, and an offset of cos(angle)*RADIUS, sin(angle)*RADIUS. That polar-to-Cartesian conversion places them evenly across the arc at a fixed radius. Editing START, SPREAD, and RADIUS reshapes the fan into a full circle, a quarter arc, or any radius.

Opening sets each item transform to its arc offset at full scale, with a transition using an overshooting cubic-bezier(.34,1.4,.5,1). The curve makes items spring slightly past their target and settle, which is the satisfying pop. Closing returns them to a stacked, scaled-down position under the trigger on the same easing.

Each item is given a transition-delay proportional to its index on open, and the order is reversed on close. That stagger makes the items fan out in sequence and fold back in sequence, which reads as the menu unfurling rather than every option blinking in at once.

Each item has a small label that fades in on hover beneath it, so the action is named when you point at it. The items also only become clickable when the menu is open, via pointer-events, so the collapsed stack under the trigger does not intercept clicks.

Compute each item angle and offset from your actions array in render, and keep an open boolean in state that toggles the transforms and stagger delays via inline styles. Add click-away and Escape handlers in a mount effect with cleanup. The spring CSS ports directly. In Tailwind, apply the transforms and transition with arbitrary values driven by the open state.

Yes. While the Radial Menu snippet gives you one pattern to copy, the free Responsive Navbar Builder at webdevpuneet.com/navbar-builder/ designs a whole navigation bar: logo, links and dropdown menus, a mobile hamburger menu (dropdown panel, slide-in drawer or full screen) and a scroll effect (sticky, shrink, hide on scroll or transparent). It has six presets, a live preview that runs the real code, and exports HTML + CSS + vanilla JS, React, Tailwind, Vue 3 or Angular — or you can click Fork & Edit to keep editing it in My Code.