Right-Click Context Menu with Anchor Positioning

Anchor a context menu to the cursor position by setting anchor-name on a hidden positioning element, then placing it at the click coordinates.

UI Patterns

Detailed Explanation

The Trick

Context menus open at the cursor's exact x/y position — not relative to a static element. Anchor positioning still works, but you need a small JavaScript shim to position the anchor at the cursor coordinates first. Then CSS handles the rest.

<div class="contextable" oncontextmenu="openMenu(event)">
  <!-- right-clickable area -->
</div>
<div class="cursor-anchor" id="cursor-anchor"></div>
<menu class="context-menu" id="context-menu" hidden>
  <li><button>Cut</button></li>
  <li><button>Copy</button></li>
  <li><button>Paste</button></li>
</menu>
#cursor-anchor {
  position: fixed;
  width: 1px;
  height: 1px;
  pointer-events: none;
  anchor-name: --cursor;
}

#context-menu {
  position: fixed;
  position-anchor: --cursor;
  position-area: bottom-end;
  margin: 4px;

  position-try-fallbacks:
    bottom-start,    /* try opening to the left */
    top-end,         /* try opening upward */
    top-start;       /* upward and left */
}
function openMenu(e) {
  e.preventDefault();
  const anchor = document.getElementById('cursor-anchor');
  anchor.style.left = e.clientX + 'px';
  anchor.style.top  = e.clientY + 'px';
  document.getElementById('context-menu').hidden = false;
}

Why a 1×1 invisible element?

The anchor needs to be a real DOM element with size and a layout box. A 1×1 pointer-events: none element is the smallest invisible target — the menu anchors to it, and the menu's own position-try-fallbacks handles edge cases (right-click near the right edge of the screen flips the menu left).

Why position: fixed?

Context menus should not scroll with the page when the user scrolls. position: fixed on both the anchor and the menu keeps them locked to the viewport, regardless of scrolling.

Avoid CSS-only at the cost of JS

You could build this without any JS by listening to mousemove to update the anchor position on every cursor move, but that's strictly worse than the imperative approach above. Use JS for the click event; let CSS handle layout.

Use Case

File-manager context menus, table-cell action menus, document-editor right-click menus, custom right-click on canvas/SVG elements, in-app right-click menus that override the browser's default context menu.

Try ItCSS Anchor Positioning Generator

Open full tool