Component

Notification Menu

Notification center dropdown with user avatars, unread indicators, timestamps, and read/unread states.

  • Component
  • Tailwind
  • HTML
  • MIT

Preview

Live component

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

Install

Add to your project

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

Source

Implementation

code.html
<!-- Notification Menu -->
<div class="relative inline-block">
  <button
    id="notification-button"
    class="relative p-2.5 text-gray-600 hover:text-blue-600 hover:bg-blue-50 rounded-lg transition-colors focus:outline-none"
    aria-expanded="true"
    aria-haspopup="true"
    onclick="toggleDropdown('notification-menu')"
  >
    <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"></path>
    </svg>
    <!-- Notification Badge -->
    <span class="absolute top-1.5 right-1.5 w-5 h-5 bg-red-500 text-white text-xs font-bold rounded-full flex items-center justify-center">3</span>
  </button>

  <div
    id="notification-menu"
    class="hidden absolute right-0 z-20 mt-2 w-96 bg-white rounded-xl shadow-2xl border border-gray-200 overflow-hidden"
  >
    <!-- Header -->
    <div class="px-5 py-4 border-b border-gray-100 flex items-center justify-between">
      <div>
        <h3 class="font-semibold text-gray-900">Notifications</h3>
        <p class="text-xs text-gray-500">You have 3 unread notifications</p>
      </div>
      <button class="text-xs font-medium text-blue-600 hover:text-blue-700">Mark all as read</button>
    </div>

    <!-- Notifications List -->
    <div class="max-h-[400px] overflow-y-auto">
      <!-- New Notification -->
      <a href="#" class="flex items-start gap-4 px-5 py-4 hover:bg-gray-50 transition-colors border-b border-gray-100">
        <div class="relative flex-shrink-0">
          <img src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=80&h=80&fit=crop&crop=faces" alt="Sarah" class="w-10 h-10 rounded-full object-cover">
          <span class="absolute -bottom-1 -right-1 w-5 h-5 bg-blue-500 rounded-full flex items-center justify-center">
            <svg class="w-3 h-3 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"></path>
            </svg>
          </span>
        </div>
        <div class="flex-1 min-w-0">
          <p class="text-sm text-gray-900"><span class="font-semibold">Sarah Chen</span> commented on your design</p>
          <p class="text-sm text-gray-500 mt-0.5">"Love the new component library! The button styles are..."</p>
          <p class="text-xs text-blue-600 mt-1">2 minutes ago</p>
        </div>
      </a>

      <!-- New Notification -->
      <a href="#" class="flex items-start gap-4 px-5 py-4 hover:bg-gray-50 transition-colors border-b border-gray-100 bg-blue-50/50">
        <div class="relative flex-shrink-0">
          <img src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=80&h=80&fit=crop&crop=faces" alt="Michael" class="w-10 h-10 rounded-full object-cover">
          <span class="absolute -top-1 -right-1 w-3 h-3 bg-red-500 rounded-full"></span>
        </div>
        <div class="flex-1 min-w-0">
          <p class="text-sm text-gray-900"><span class="font-semibold">Michael Park</span> mentioned you in a project</p>
          <p class="text-sm text-gray-500 mt-0.5">@alex.chen check out the new dashboard design</p>
          <p class="text-xs text-gray-400 mt-1">15 minutes ago</p>
        </div>
      </a>

      <!-- New Notification -->
      <a href="#" class="flex items-start gap-4 px-5 py-4 hover:bg-gray-50 transition-colors border-b border-gray-100">
        <div class="relative flex-shrink-0">
          <img src="https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=80&h=80&fit=crop&crop=faces" alt="Emma" class="w-10 h-10 rounded-full object-cover">
        </div>
        <div class="flex-1 min-w-0">
          <p class="text-sm text-gray-900"><span class="font-semibold">Emma Wilson</span> shared a file with you</p>
          <p class="text-sm text-gray-500 mt-0.5">Design_System_v2.fig shared</p>
          <p class="text-xs text-gray-400 mt-1">1 hour ago</p>
        </div>
      </a>

      <!-- Read Notification -->
      <a href="#" class="flex items-start gap-4 px-5 py-4 hover:bg-gray-50 transition-colors border-b border-gray-100 opacity-60">
        <div class="flex-shrink-0">
          <div class="w-10 h-10 rounded-full bg-emerald-100 flex items-center justify-center">
            <svg class="w-5 h-5 text-emerald-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
            </svg>
          </div>
        </div>
        <div class="flex-1 min-w-0">
          <p class="text-sm text-gray-900">Your subscription was renewed</p>
          <p class="text-sm text-gray-500 mt-0.5">Pro plan - Next billing date: Dec 15</p>
          <p class="text-xs text-gray-400 mt-1">Yesterday</p>
        </div>
      </a>

      <!-- Read Notification -->
      <a href="#" class="flex items-start gap-4 px-5 py-4 hover:bg-gray-50 transition-colors opacity-60">
        <div class="flex-shrink-0">
          <div class="w-10 h-10 rounded-full bg-purple-100 flex items-center justify-center">
            <svg class="w-5 h-5 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01"></path>
            </svg>
          </div>
        </div>
        <div class="flex-1 min-w-0">
          <p class="text-sm text-gray-900">New component pack released</p>
          <p class="text-sm text-gray-500 mt-0.5">30 new dropdown components are now available</p>
          <p class="text-xs text-gray-400 mt-1">2 days ago</p>
        </div>
      </a>
    </div>

    <!-- Footer -->
    <div class="px-5 py-3 border-t border-gray-100 bg-gray-50">
      <a href="#" class="block text-center text-sm font-medium text-blue-600 hover:text-blue-700 transition-colors">
        View all notifications
      </a>
    </div>
  </div>
</div>

<script>
  function toggleDropdown(id) {
    const menu = document.getElementById(id);
    menu.classList.toggle('hidden');
    const button = document.getElementById('notification-button');
    const isExpanded = button.getAttribute('aria-expanded') === 'true';
    button.setAttribute('aria-expanded', !isExpanded);
  }

  document.addEventListener('click', function(event) {
    const dropdown = document.querySelector('.relative.inline-block');
    const button = document.getElementById('notification-button');
    const menu = document.getElementById('notification-menu');
    if (!dropdown.contains(event.target)) {
      menu.classList.add('hidden');
      button.setAttribute('aria-expanded', 'false');
    }
  });
</script>
134 lines UTF-8 · LF · Spaces: 2

AI-ready

Available to your agent.

This component is reachable through the DevSnips CLI, MCP server and Skills integrations — one registry, one resource path.

Resource path

devsnips://components/dropdowns/notification-menu

Continue browsing

View all