DEV Community

Cover image for Real-Time Notifications UI with Tailwind CSS and WebSockets
HexShift
HexShift

Posted on

Real-Time Notifications UI with Tailwind CSS and WebSockets

Adding real-time features to your web app can significantly boost engagement by instantly informing users without page reloads. In this tutorial, we’ll build a notification dropdown panel using Tailwind CSS for styling and WebSockets for live updates—framework-agnostic and easy to copy into any stack.


Why Real-Time Notifications?

  • Keeps users updated instantly
  • Improves engagement with live feedback
  • Enhances UX by avoiding manual refreshes

HTML & Tailwind Setup

<div class="relative"> <button id="notif-btn" class="relative p-2 focus:outline-none"> 🔔 <span id="notif-count" class="absolute -top-1 -right-1 bg-red-600 text-white text-xs w-5 h-5 rounded-full flex items-center justify-center hidden">!</span> </button> <div id="notif-panel" class="hidden absolute right-0 mt-2 w-80 bg-white dark:bg-gray-800 shadow-lg rounded-lg overflow-hidden max-h-96 overflow-y-auto transition-opacity duration-200"> <!-- Notifications go here --> </div> </div> 
Enter fullscreen mode Exit fullscreen mode
  • Wrapper is relative, panel is absolute for floating
  • Badge uses bg-red-600, rounded-full, and position utilities
  • Panel styled with shadow-lg, rounded-lg, and scrollable behavior

WebSocket Integration

const btn = document.getElementById('notif-btn'); const panel = document.getElementById('notif-panel'); const count = document.getElementById('notif-count'); let unseen = 0; btn.addEventListener('click', () => { panel.classList.toggle('hidden'); if (!panel.classList.contains('hidden')) { unseen = 0; count.classList.add('hidden'); } }); // Initialize WebSocket (add your own URL) const ws = new WebSocket('wss://your.api/notifications'); ws.onmessage = (e) => { const data = JSON.parse(e.data); const item = document.createElement('div'); item.className = 'flex items-start px-4 py-3 border-b border-gray-200 dark:border-gray-700'; item.innerHTML = ` <div class="flex-1"> <p class="font-semibold text-gray-800 dark:text-gray-100">${data.title}</p> <p class="text-sm text-gray-600 dark:text-gray-300">${data.message}</p> <p class="text-xs text-gray-400">${data.timestamp}</p> </div>`; panel.prepend(item); unseen += 1; count.textContent = unseen; count.classList.remove('hidden'); }; 
Enter fullscreen mode Exit fullscreen mode
  • Toggles visibility via hidden class
  • WebSocket listens for JSON messages, prepends notifications
  • Increment badge count for unseen messages

Responsive & Interactive Touches

  • Use w-full sm:w-80 for mobile adaptability
  • Add transition-opacity duration-200 for smooth panel appearance
  • Make badge smaller on mobile if needed with responsive text sizing

Accessibility Recommendations

  • Ensure badge has aria-label="X new notifications" updated on change
  • Manage focus: return focus to button after opening/closing
  • Use roles like role="menu" and aria-expanded on button

About the 37‑Page PDF Guide

If you're building real-time UIs or complex interactive components, Mastering Tailwind at Scale: Architecture, Patterns & Performance dives deep into:

  • Component structure patterns for dynamic systems
  • Theming, utility scoping, and responsive design at scale
  • Performance tuning for both CSS and JavaScript
  • Integration patterns with frameworks (React, Vue, etc.), WebSockets, backend services, and WASM
  • Practical examples and architecture blueprints covering real-time features like notifications

This 37‑page guide is on Gumroad for $10, giving you detailed diagrams, reusable snippets, and strategies to scale your Tailwind-powered frontend consistently and efficiently.

👉 Get the guide here:

Mastering Tailwind at Scale: Architecture, Patterns & Performance


Give your users feedback that feels instantaneous and polished—build live notifications with Tailwind and WebSockets today!

Top comments (0)