Component

Floating Menu

Contextual floating menu that appears at click position with screen-edge detection and backdrop blur.

  • Component
  • Tailwind
  • HTML
  • MIT

Preview

Live component

Interactive preview
Open preview
9:41 100%
devsnips.site/library/tailwind/components/dropdowns/floating-menu/
fluid · no fixed width 100%
No dependencies Production-ready

Install

Add to your project

terminal
npx devsnips add Tailwind/Components/Dropdowns/floating-menu
registry path: Tailwind/Components/Dropdowns/floating-menu

Source

Implementation

code.html
<!-- Floating Menu (Contextual Tool Palette) -->
<div class="relative">
  <div
    id="floating-trigger"
    class="w-full max-w-md mx-auto p-16 bg-gradient-to-br from-gray-50 to-gray-100 border-2 border-dashed border-gray-300 rounded-2xl text-center"
  >
    <p class="text-gray-500 mb-4">Click anywhere on this card to open the floating menu</p>
    <p class="text-sm text-gray-400">The menu will appear at your click position</p>
  </div>

  <!-- Floating Menu (appears at click position) -->
  <div
    id="floating-menu"
    class="hidden fixed z-50 w-64 bg-white rounded-2xl shadow-2xl border border-gray-100 overflow-hidden backdrop-blur-sm bg-white/95"
    style="left: 0; top: 0;"
  >
    <!-- Header -->
    <div class="px-4 py-3 bg-gradient-to-r from-blue-600 to-indigo-600">
      <div class="flex items-center gap-3">
        <div class="w-10 h-10 rounded-xl bg-white/20 flex items-center justify-center">
          <svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
          </svg>
        </div>
        <div>
          <p class="text-white font-semibold">Quick Tools</p>
          <p class="text-blue-100 text-xs">Select an action</p>
        </div>
      </div>
    </div>

    <!-- Tool List -->
    <div class="py-2">
      <button class="w-full flex items-center gap-3 px-4 py-3 text-gray-700 hover:bg-blue-50 transition-colors">
        <div class="w-8 h-8 rounded-lg bg-blue-100 flex items-center justify-center text-blue-600">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
          </svg>
        </div>
        <span class="text-sm font-medium">Edit</span>
        <span class="ml-auto text-xs text-gray-400">⌘E</span>
      </button>

      <button class="w-full flex items-center gap-3 px-4 py-3 text-gray-700 hover:bg-blue-50 transition-colors">
        <div class="w-8 h-8 rounded-lg bg-emerald-100 flex items-center justify-center text-emerald-600">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"></path>
          </svg>
        </div>
        <span class="text-sm font-medium">Duplicate</span>
        <span class="ml-auto text-xs text-gray-400">⌘D</span>
      </button>

      <button class="w-full flex items-center gap-3 px-4 py-3 text-gray-700 hover:bg-blue-50 transition-colors">
        <div class="w-8 h-8 rounded-lg bg-purple-100 flex items-center justify-center text-purple-600">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z"></path>
          </svg>
        </div>
        <span class="text-sm font-medium">Share</span>
        <span class="ml-auto text-xs text-gray-400">⌘⇧S</span>
      </button>
    </div>

    <!-- Divider -->
    <div class="border-t border-gray-100"></div>

    <!-- Secondary Actions -->
    <div class="py-2">
      <button class="w-full flex items-center gap-3 px-4 py-3 text-gray-700 hover:bg-gray-50 transition-colors">
        <div class="w-8 h-8 rounded-lg bg-gray-100 flex items-center justify-center text-gray-600">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path>
          </svg>
        </div>
        <span class="text-sm">Download</span>
      </button>

      <button class="w-full flex items-center gap-3 px-4 py-3 text-red-600 hover:bg-red-50 transition-colors">
        <div class="w-8 h-8 rounded-lg bg-red-100 flex items-center justify-center text-red-600">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
          </svg>
        </div>
        <span class="text-sm">Delete</span>
      </button>
    </div>
  </div>
</div>

<script>
  const trigger = document.getElementById('floating-trigger');
  const menu = document.getElementById('floating-menu');

  trigger.addEventListener('click', function(event) {
    menu.classList.remove('hidden');
    
    // Position menu at click location
    const rect = trigger.getBoundingClientRect();
    let x = event.clientX;
    let y = event.clientY;
    
    // Adjust if menu would go off screen
    const menuWidth = 256;
    const menuHeight = menu.offsetHeight;
    
    if (x + menuWidth > window.innerWidth) {
      x = window.innerWidth - menuWidth - 10;
    }
    if (y + menuHeight > window.innerHeight) {
      y = window.innerHeight - menuHeight - 10;
    }
    
    menu.style.left = x + 'px';
    menu.style.top = y + 'px';
    
    // Add appear animation
    menu.style.opacity = '0';
    menu.style.transform = 'scale(0.9)';
    menu.style.transition = 'all 0.2s ease-out';
    
    requestAnimationFrame(() => {
      menu.style.opacity = '1';
      menu.style.transform = 'scale(1)';
    });
  });

  document.addEventListener('click', function(event) {
    if (!menu.contains(event.target) && !trigger.contains(event.target)) {
      menu.classList.add('hidden');
    }
  });
</script>
133 lines UTF-8 · LF · Spaces: 2
DevSnips AI ready Claude · Cursor · Windsurf

Agent skill & Model Context Protocol

Pass this component straight into your AI workflow. DevSnips exposes each resource as a structured, addressable registry entry, so your agent installs the real files instead of approximating them.

devsnips://components/dropdowns/floating-menu
Prompt instruction
I want to use this DevSnips resource in production:

Page:
https://devsnips.site/library/tailwind/components/dropdowns/floating-menu/

Install: npx devsnips add
Tailwind/Components/Dropdowns/floating-menu

This is the Floating Menu — Contextual floating menu that appears at click position with screen-edge detection and backdrop blur.

Use this DevSnips resource as the starting point for my project.
Adapt it to my project's stack and conventions, fix any issues,
and make it production-ready while preserving its intended design
and behavior.

Paste into ChatGPT, Claude or your agent — it already carries the page URL and the exact install path.

Resource URI
devsnips://components/dropdowns/floating-menu