Radial Right-Click Menu — Free Circular Context Menu Snippet

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

Share & Support

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.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You don't have to work out the contextmenu wiring and polar placement math from scratch. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly why e.preventDefault() inside the contextmenu handler is what suppresses the browser's native right-click menu, and how the angle formula (index / total) * 2 * Math.PI, offset by -Math.PI / 2, spaces every item evenly around a full circle starting from 12 o'clock instead of 3 o'clock. The same assistant can help you optimize it — for instance asking whether the menu should detect when RADIUS would push items off-screen near a viewport edge and shrink or reposition itself accordingly, similar to the edge-clamping in a standard rectangular context menu. It's also useful for extending the menu: ask it to support a partial arc instead of a full circle for edge-anchored triggers, add keyboard arrow-key navigation that moves focus between items in angular order, or make different right-clicked elements open different action sets via event delegation. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a "radial right-click menu" in plain HTML, CSS, and JavaScript — a circular context menu that opens centered on the real right-click point, replacing the browser's native menu entirely.

Requirements:
- Listen for the actual contextmenu event on a target area (not a click substitute), call e.preventDefault() inside the handler so the browser's native context menu never appears, and use the event's clientX/clientY as the menu's center origin.
- Render a fixed set of circular action items (e.g. six), each placed around the click origin using polar-to-Cartesian math: for item index i out of N total items, compute an angle of (i / N) * 2 * Math.PI (optionally offset so the first item starts at a specific clock position), then convert to an offset with Math.cos(angle) * RADIUS and Math.sin(angle) * RADIUS, and add that offset to the click origin's x/y to get each item's absolute position — this layout must be recalculated fresh every time the menu opens at a new coordinate, not hardcoded.
- Items must be hidden and scaled down at rest, becoming visible and springing out to their computed positions when the menu opens, using a CSS transition with an overshooting easing curve so they visibly pop outward from the exact right-click point rather than just fading in.
- Each item must be independently clickable/selectable (a real click target, not purely decorative), closing the menu and reporting which action was selected.
- Implement multiple ways to close the menu: clicking anywhere outside it, right-clicking outside the original target area, pressing Escape, and scrolling the page (since the menu is positioned at fixed viewport coordinates and would otherwise visually detach from its anchor point if the page scrolled while it stayed open).
- Show a small tooltip label on hover for each icon-only item so the action is identifiable without requiring prior memorization of the icon set.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

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
A circular alternative to a context menu.
Game-style interfaces
Radial wheels are a familiar pattern from game UIs.
Map and diagram editors
Fan out actions around a right-clicked map point.
Whiteboard and node editors
Right-click a node for circular quick actions.
Data grids
Pair with a table row context menu for per-row wheels.
Learning contextmenu + trigonometry
A reference for real right-click events and polar placement.

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.