webdevpuneet.com

Radial Right-Click Menu — Free Circular Context Menu Snippet

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

CategoryNavigation

Copy & paste

Source Code

<div class="rrc-stage" id="rrcStage">
  <p class="rrc-hint">Right-click anywhere in this area</p>
</div>
<div class="rrc-menu" id="rrcMenu"></div>
<p class="rrc-log" id="rrcLog"></p>

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

Real contextmenu event
preventDefault suppresses the native browser menu.
Cursor-anchored origin
The wheel centers on the exact right-click point.
Even polar spacing
cos/sin placement spaces items around a full circle.
Spring-out animation
An overshooting easing pops items from the center.
Multiple close paths
Click-away, second right-click, Escape, and scroll.
Hover labels
Tooltips name each icon-only action.
Recomputed per open
Layout math reruns fresh at every click point.
No dependency
Pure HTML/CSS/JS — no context-menu library.

About this UI Snippet

Radial Right-Click Menu — Circular Actions Around the Click Point

Screenshot of the Radial Right-Click Menu snippet rendered live

This replaces the familiar rectangular right-click list — see context menu for that version — with a circular fan of actions centered exactly where you right-clicked, closer in spirit to a game's radial wheel menu than a desktop app's dropdown. It listens for the real contextmenu event and suppresses the browser's own menu, then places each action around the click point using the same polar coordinate math behind a click-triggered radial menu.

A real contextmenu event, not a click substitute

The stage listens for contextmenu (which fires on an actual right-click or a platform's equivalent gesture) and immediately calls e.preventDefault() — without that line, the browser's native menu would appear layered on top of the custom one. e.clientX/e.clientY from that event become the menu's origin, so the wheel always opens exactly where the cursor was, not at a fixed screen position.

Items placed by polar-to-Cartesian math

For six actions arranged around a full circle, each item's angle is (i / 6) * 2π - π/2 — evenly spaced around 360°, with the - π/2 offset rotating the first item to 12 o'clock instead of 3 o'clock. Converting that angle to an (x, y) offset via cos(angle) * RADIUS/sin(angle) * RADIUS and adding it to the click origin places every item at an identical distance from the center, evenly spaced — this is recomputed on every open, so the wheel always centers correctly no matter where on the stage you right-click.

Spring-out animation from the center

Every item starts scaled to 0.3 and stacked at the menu's own (0,0) transform origin with opacity: 0; opening sets each item's absolute left/top to its precomputed offset and toggles the .open class, which is what triggers the CSS transition on transform/opacity — combined with an overshooting cubic-bezier, items visibly spring outward from the exact point you clicked, reinforcing that the menu is anchored to your cursor rather than the page.

Closing from every direction

The menu closes on a plain click anywhere, a *second* right-click outside the stage (so context-menuing elsewhere doesn't leave two menus open), Escape, and on scroll — since a radial menu anchored to fixed pixel coordinates would otherwise visually detach from whatever it was opened over if the page moved underneath it.

Customizing it

Change RADIUS, the action list, or the starting angle offset; make the menu open only over specific elements with e.target.closest(); or combine it with a table row context menu pattern for per-row circular actions in a data grid.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSAn empty stage renders with a right-click hint.
  2. 2
    Right-click inside the stageThe native menu is suppressed; a circular menu opens there.
  3. 3
    Move toward or click an iconSix actions are evenly spaced around the click point.
  4. 4
    Select an actionA log line confirms the selection and the menu closes.
  5. 5
    Click elsewhere, scroll, or press EscapeAny of these dismiss the open menu.
  6. 6
    Reshape the wheelEdit RADIUS, ACTIONS, or the starting angle.

Real-world uses

Common Use Cases

Canvas and design tools
Provide a circular alternative to a context menu, centred on the exact point of a real contextmenu event.
Game-style interfaces
Use the radial wheel pattern familiar from games, with items placed around a full circle through cos and sin.
Map and diagram editors
Fan actions out around a right-click point in map and diagram editors, with preventDefault suppressing the native browser menu entirely.
Whiteboard and node editors
Right-click a node in a whiteboard or node editor for circular actions, using a spring-out animation from the centre of the wheel.
Data grid pairings
Pair with a table row context menu for per-row actions, and learn polar to Cartesian placement.
Related: Tabs with URL Sync
See the Tabs with URL Sync for a related navigation pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

The stage listens for the real contextmenu event, which fires on an actual right-click, and immediately calls e.preventDefault() inside the handler. Without that call, the browser's own context menu would render on top of the custom radial menu; with it, only the circular menu appears, positioned at the event's clientX/clientY.

Each item's angle is (index / total) * 2 * Math.PI, offset by -Math.PI/2 so the first item lands at 12 o'clock instead of 3 o'clock. That angle is converted to an x/y offset with cos(angle) * RADIUS and sin(angle) * RADIUS — standard polar-to-Cartesian conversion — and added to the click origin, placing every item at an identical distance from the center with even angular spacing. This recomputes on every open based on the current click coordinates.

Each item is a real element with its own click handler and a generous 52px circular hit area, so moving the cursor near an icon and clicking it works the same as clicking any button — the polar layout keeps every item an equal, predictable distance from the center, which is what makes moving toward one by feel practical once you're familiar with the wheel's arrangement.

The menu is positioned with fixed-position, viewport-relative coordinates captured at the moment it opened. If the page scrolled while the menu stayed open, its circle would visually detach from whatever element it was originally opened over. Closing on scroll (using a capturing listener so it catches scroll on any nested scrollable ancestor) avoids that mismatch.

Keep an open boolean and an { x, y } origin in state, and compute each item's angle/offset from that origin in render (or via a small memoized helper). Attach the contextmenu listener to your target element's ref, call preventDefault, and set the origin from the event. Handle click-away, Escape, and scroll dismissal in a mount effect with cleanup.

Yes. While the Radial Right-Click 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.