32 CSS Floating Action Button Designs 13 / 32
Notification Bell FAB
Floating notification bell button with ring animation, multiple badge variants, and an interactive dropdown notification panel.
The code
<div class="fb13">
<h1>Floating Notification Bell</h1>
<p class="fb13-sub">Animated bell FAB with number badge, pulse ring, and an expandable notification dropdown. Hover any bell to hear it ring.</p>
<div class="fb13-scene">
<!-- Dark bordered -->
<div class="fb13-card">
<span class="fb13-card-tag">Dark bordered</span>
<button class="fb13-bell-fab fb13-bell-fab--dark" aria-label="Notifications (7 unread)">
<svg class="fb13-bell-icon" viewBox="0 0 24 24"><path d="M12 22c1.1 0 2-.9 2-2h-4a2 2 0 002 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"/></svg>
<span class="fb13-bell-badge fb13-bell-badge--pulse">7</span>
</button>
<span style="font-size:.72rem;color:#475569">Hover to ring</span>
</div>
<!-- Indigo filled -->
<div class="fb13-card">
<span class="fb13-card-tag">Indigo filled</span>
<button class="fb13-bell-fab fb13-bell-fab--indigo" aria-label="Notifications (3 unread)">
<svg class="fb13-bell-icon" viewBox="0 0 24 24"><path d="M12 22c1.1 0 2-.9 2-2h-4a2 2 0 002 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"/></svg>
<span class="fb13-bell-badge">3</span>
</button>
</div>
<!-- Amber alert -->
<div class="fb13-card">
<span class="fb13-card-tag">Amber alert</span>
<button class="fb13-bell-fab fb13-bell-fab--amber fb13-bell-fab--auto" aria-label="Alerts">
<svg class="fb13-bell-icon" viewBox="0 0 24 24"><path d="M12 22c1.1 0 2-.9 2-2h-4a2 2 0 002 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"/></svg>
<span class="fb13-bell-badge" style="background:#ef4444">!</span>
</button>
<span style="font-size:.72rem;color:#475569">Auto-rings</span>
</div>
<!-- Dot + muted -->
<div class="fb13-card">
<span class="fb13-card-tag">Green dot · muted</span>
<div style="display:flex;gap:20px;align-items:center">
<button class="fb13-bell-fab fb13-bell-fab--indigo" style="width:54px;height:54px" aria-label="New notification">
<svg class="fb13-bell-icon" viewBox="0 0 24 24" style="width:22px;height:22px"><path d="M12 22c1.1 0 2-.9 2-2h-4a2 2 0 002 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"/></svg>
<span class="fb13-bell-badge fb13-bell-badge--dot"></span>
</button>
<button class="fb13-bell-fab fb13-bell-fab--muted" style="width:54px;height:54px" aria-label="Notifications (none)">
<svg class="fb13-bell-icon" viewBox="0 0 24 24" style="width:22px;height:22px"><path d="M12 22c1.1 0 2-.9 2-2h-4a2 2 0 002 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"/></svg>
</button>
</div>
</div>
<!-- Interactive dropdown -->
<div class="fb13-card" style="grid-column: span 2" id="fb13-card-dropdown">
<span class="fb13-card-tag">Interactive dropdown — click the bell</span>
<div class="fb13-interactive-wrap">
<button class="fb13-bell-fab fb13-bell-fab--indigo" id="fb13-notif-bell" aria-label="Open notifications" aria-expanded="false">
<svg class="fb13-bell-icon" viewBox="0 0 24 24"><path d="M12 22c1.1 0 2-.9 2-2h-4a2 2 0 002 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"/></svg>
<span class="fb13-bell-badge" id="fb13-notif-count">4</span>
</button>
<div class="fb13-notif-panel" id="fb13-notif-panel">
<div class="fb13-np-header">
<span>Notifications</span>
<small id="fb13-mark-read">Mark all read</small>
</div>
<div class="fb13-np-item">
<div class="fb13-np-dot fb13-np-dot--blue"></div>
<div class="fb13-np-text">
<strong>Alex Chen</strong> <span>mentioned you in a comment</span>
<time class="fb13-np-time">2 min ago</time>
</div>
</div>
<div class="fb13-np-item">
<div class="fb13-np-dot fb13-np-dot--green"></div>
<div class="fb13-np-text">
<strong>Deploy succeeded</strong> <span>production · v2.4.1</span>
<time class="fb13-np-time">14 min ago</time>
</div>
</div>
<div class="fb13-np-item">
<div class="fb13-np-dot fb13-np-dot--amber"></div>
<div class="fb13-np-text">
<strong>Payment received</strong> <span>Invoice #2047 paid</span>
<time class="fb13-np-time">1 hour ago</time>
</div>
</div>
<div class="fb13-np-item">
<div class="fb13-np-dot fb13-np-dot--blue"></div>
<div class="fb13-np-text">
<strong>Mia Torres</strong> <span>shared a file with you</span>
<time class="fb13-np-time">3 hours ago</time>
</div>
</div>
</div>
</div>
</div>
</div>
</div> <div class="fb13">
<h1>Floating Notification Bell</h1>
<p class="fb13-sub">Animated bell FAB with number badge, pulse ring, and an expandable notification dropdown. Hover any bell to hear it ring.</p>
<div class="fb13-scene">
<!-- Dark bordered -->
<div class="fb13-card">
<span class="fb13-card-tag">Dark bordered</span>
<button class="fb13-bell-fab fb13-bell-fab--dark" aria-label="Notifications (7 unread)">
<svg class="fb13-bell-icon" viewBox="0 0 24 24"><path d="M12 22c1.1 0 2-.9 2-2h-4a2 2 0 002 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"/></svg>
<span class="fb13-bell-badge fb13-bell-badge--pulse">7</span>
</button>
<span style="font-size:.72rem;color:#475569">Hover to ring</span>
</div>
<!-- Indigo filled -->
<div class="fb13-card">
<span class="fb13-card-tag">Indigo filled</span>
<button class="fb13-bell-fab fb13-bell-fab--indigo" aria-label="Notifications (3 unread)">
<svg class="fb13-bell-icon" viewBox="0 0 24 24"><path d="M12 22c1.1 0 2-.9 2-2h-4a2 2 0 002 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"/></svg>
<span class="fb13-bell-badge">3</span>
</button>
</div>
<!-- Amber alert -->
<div class="fb13-card">
<span class="fb13-card-tag">Amber alert</span>
<button class="fb13-bell-fab fb13-bell-fab--amber fb13-bell-fab--auto" aria-label="Alerts">
<svg class="fb13-bell-icon" viewBox="0 0 24 24"><path d="M12 22c1.1 0 2-.9 2-2h-4a2 2 0 002 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"/></svg>
<span class="fb13-bell-badge" style="background:#ef4444">!</span>
</button>
<span style="font-size:.72rem;color:#475569">Auto-rings</span>
</div>
<!-- Dot + muted -->
<div class="fb13-card">
<span class="fb13-card-tag">Green dot · muted</span>
<div style="display:flex;gap:20px;align-items:center">
<button class="fb13-bell-fab fb13-bell-fab--indigo" style="width:54px;height:54px" aria-label="New notification">
<svg class="fb13-bell-icon" viewBox="0 0 24 24" style="width:22px;height:22px"><path d="M12 22c1.1 0 2-.9 2-2h-4a2 2 0 002 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"/></svg>
<span class="fb13-bell-badge fb13-bell-badge--dot"></span>
</button>
<button class="fb13-bell-fab fb13-bell-fab--muted" style="width:54px;height:54px" aria-label="Notifications (none)">
<svg class="fb13-bell-icon" viewBox="0 0 24 24" style="width:22px;height:22px"><path d="M12 22c1.1 0 2-.9 2-2h-4a2 2 0 002 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"/></svg>
</button>
</div>
</div>
<!-- Interactive dropdown -->
<div class="fb13-card" style="grid-column: span 2" id="fb13-card-dropdown">
<span class="fb13-card-tag">Interactive dropdown — click the bell</span>
<div class="fb13-interactive-wrap">
<button class="fb13-bell-fab fb13-bell-fab--indigo" id="fb13-notif-bell" aria-label="Open notifications" aria-expanded="false">
<svg class="fb13-bell-icon" viewBox="0 0 24 24"><path d="M12 22c1.1 0 2-.9 2-2h-4a2 2 0 002 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"/></svg>
<span class="fb13-bell-badge" id="fb13-notif-count">4</span>
</button>
<div class="fb13-notif-panel" id="fb13-notif-panel">
<div class="fb13-np-header">
<span>Notifications</span>
<small id="fb13-mark-read">Mark all read</small>
</div>
<div class="fb13-np-item">
<div class="fb13-np-dot fb13-np-dot--blue"></div>
<div class="fb13-np-text">
<strong>Alex Chen</strong> <span>mentioned you in a comment</span>
<time class="fb13-np-time">2 min ago</time>
</div>
</div>
<div class="fb13-np-item">
<div class="fb13-np-dot fb13-np-dot--green"></div>
<div class="fb13-np-text">
<strong>Deploy succeeded</strong> <span>production · v2.4.1</span>
<time class="fb13-np-time">14 min ago</time>
</div>
</div>
<div class="fb13-np-item">
<div class="fb13-np-dot fb13-np-dot--amber"></div>
<div class="fb13-np-text">
<strong>Payment received</strong> <span>Invoice #2047 paid</span>
<time class="fb13-np-time">1 hour ago</time>
</div>
</div>
<div class="fb13-np-item">
<div class="fb13-np-dot fb13-np-dot--blue"></div>
<div class="fb13-np-text">
<strong>Mia Torres</strong> <span>shared a file with you</span>
<time class="fb13-np-time">3 hours ago</time>
</div>
</div>
</div>
</div>
</div>
</div>
</div>.fb13, .fb13 *, .fb13 *::before, .fb13 *::after { box-sizing: border-box; margin: 0; padding: 0; }
.fb13 {
font-family: 'Inter', sans-serif;
background: #0f172a;
min-height: 100vh;
display: grid;
place-items: center;
padding: 40px 20px;
color: #e2e8f0;
}
h1 {
font-size: clamp(1.6rem, 5vw, 2.4rem);
font-weight: 700;
text-align: center;
letter-spacing: -.022em;
margin-bottom: 8px;
}
p.fb13-sub {
text-align: center;
color: #475569;
font-size: .9rem;
max-width: 44ch;
margin: 0 auto 52px;
line-height: 1.6;
}
.fb13-scene {
width: min(780px, 100%);
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 20px;
}
.fb13-card {
background: #1e293b;
border: 1px solid #334155;
border-radius: 20px;
padding: 36px 24px;
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
position: relative;
overflow: hidden;
}
.fb13-card::before {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(ellipse 80% 60% at 50% -10%, rgba(99,102,241,.06), transparent);
pointer-events: none;
}
.fb13-card-tag {
font-size: .66rem;
font-weight: 600;
letter-spacing: .1em;
text-transform: uppercase;
color: #475569;
}
/* ── BELL FAB ── */
.fb13-bell-fab {
position: relative;
width: 66px;
height: 66px;
border-radius: 50%;
border: none;
cursor: pointer;
display: grid;
place-items: center;
outline: none;
transition: transform .22s cubic-bezier(.34,1.56,.64,1), box-shadow .2s;
}
/* Variant 1: Classic dark */
.fb13-bell-fab--dark {
background: #1e293b;
border: 1.5px solid #334155;
box-shadow: 0 4px 16px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.06);
}
.fb13-bell-fab--dark:hover {
transform: scale(1.1);
box-shadow: 0 8px 28px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.08);
border-color: #4f46e5;
}
/* Variant 2: Indigo filled */
.fb13-bell-fab--indigo {
background: linear-gradient(135deg, #6366f1, #4f46e5);
box-shadow: 0 6px 22px rgba(99,102,241,.45), inset 0 1px 0 rgba(255,255,255,.18);
}
.fb13-bell-fab--indigo:hover {
transform: scale(1.1);
box-shadow: 0 10px 32px rgba(99,102,241,.6), inset 0 1px 0 rgba(255,255,255,.2);
}
/* Variant 3: Amber alert */
.fb13-bell-fab--amber {
background: linear-gradient(135deg, #f59e0b, #d97706);
box-shadow: 0 6px 22px rgba(245,158,11,.45), inset 0 1px 0 rgba(255,255,255,.18);
}
.fb13-bell-fab--amber:hover {
transform: scale(1.1);
box-shadow: 0 10px 32px rgba(245,158,11,.6), inset 0 1px 0 rgba(255,255,255,.2);
}
/* Variant 4: Muted (no unread) */
.fb13-bell-fab--muted {
background: #1e293b;
border: 1.5px solid #2d3f55;
box-shadow: 0 2px 8px rgba(0,0,0,.4);
}
.fb13-bell-fab--muted:hover {
transform: scale(1.08);
border-color: #64748b;
}
/* bell icon */
.fb13-bell-fab svg.fb13-bell-icon {
width: 28px;
height: 28px;
position: relative;
z-index: 1;
}
.fb13-bell-fab--dark svg.fb13-bell-icon,
.fb13-bell-fab--muted svg.fb13-bell-icon { fill: #94a3b8; }
.fb13-bell-fab--indigo svg.fb13-bell-icon,
.fb13-bell-fab--amber svg.fb13-bell-icon { fill: #fff; }
/* bell ring animation */
@keyframes fb13-bell-ring {
0% { transform: rotate(0deg); }
10% { transform: rotate(12deg); }
20% { transform: rotate(-10deg); }
30% { transform: rotate(8deg); }
40% { transform: rotate(-6deg); }
50% { transform: rotate(4deg); }
60% { transform: rotate(-2deg); }
70% { transform: rotate(0deg); }
100% { transform: rotate(0deg); }
}
.fb13-bell-fab:hover .fb13-bell-icon,
.fb13-bell-fab:focus .fb13-bell-icon { animation: fb13-bell-ring .6s ease-in-out; }
.fb13-bell-fab--auto .fb13-bell-icon { animation: fb13-bell-ring 1s ease-in-out 1s infinite; animation-play-state: running; }
/* notification badge */
.fb13-bell-badge {
position: absolute;
top: 0;
right: 0;
min-width: 22px;
height: 22px;
border-radius: 11px;
background: #ef4444;
color: #fff;
font-size: .65rem;
font-weight: 700;
display: grid;
place-items: center;
padding: 0 5px;
border: 2.5px solid #0f172a;
z-index: 2;
transform: translate(4px, -4px);
animation: fb13-badge-in .4s cubic-bezier(.34,1.56,.64,1) both;
}
@keyframes fb13-badge-in {
from { transform: translate(4px,-4px) scale(0); }
to { transform: translate(4px,-4px) scale(1); }
}
/* pulsing badge */
.fb13-bell-badge--pulse { animation: fb13-badge-in .4s cubic-bezier(.34,1.56,.64,1) both, fb13-badge-pulse 2s ease-in-out 1s infinite; }
@keyframes fb13-badge-pulse {
0%,100% { box-shadow: 0 0 0 0 rgba(239,68,68,.5); }
50% { box-shadow: 0 0 0 6px rgba(239,68,68,0); }
}
/* dot badge (no number) */
.fb13-bell-badge--dot {
width: 13px;
height: 13px;
min-width: 0;
padding: 0;
border-radius: 50%;
background: #22c55e;
}
/* notification dropdown panel (for the JS variant) */
.fb13-notif-panel {
position: absolute;
top: calc(100% + 10px);
right: 0;
width: 280px;
background: #1e293b;
border: 1px solid #334155;
border-radius: 16px;
box-shadow: 0 16px 48px rgba(0,0,0,.6);
overflow: hidden;
opacity: 0;
transform: translateY(-8px) scale(.97);
pointer-events: none;
transform-origin: top right;
transition: opacity .25s ease, transform .28s cubic-bezier(.34,1.56,.64,1);
z-index: 20;
}
.fb13-notif-panel.fb13-open { opacity: 1; transform: none; pointer-events: auto; }
.fb13-np-header {
padding: 14px 16px;
border-bottom: 1px solid #334155;
display: flex;
align-items: center;
justify-content: space-between;
}
.fb13-np-header span { font-size: .8rem; font-weight: 600; color: #e2e8f0; }
.fb13-np-header small { font-size: .7rem; color: #6366f1; cursor: pointer; }
.fb13-np-item {
padding: 12px 16px;
border-bottom: 1px solid #1e293b;
display: flex;
gap: 10px;
cursor: pointer;
transition: background .1s;
}
.fb13-np-item:hover { background: #243449; }
.fb13-np-item:last-child { border: 0; }
.fb13-np-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; margin-top: 5px; }
.fb13-np-dot--blue { background: #6366f1; }
.fb13-np-dot--green { background: #22c55e; }
.fb13-np-dot--amber { background: #f59e0b; }
.fb13-np-dot--empty { background: transparent; border: 1px solid #334155; }
.fb13-np-text { font-size: .78rem; line-height: 1.4; }
.fb13-np-text strong { color: #e2e8f0; font-weight: 600; }
.fb13-np-text span { color: #64748b; }
.fb13-np-time { font-size: .66rem; color: #475569; margin-top: 3px; display: block; }
/* wrapper for interactive demo */
.fb13-interactive-wrap {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
}
@media (prefers-reduced-motion: reduce) {
.fb13-bell-fab svg.fb13-bell-icon,
.fb13-bell-fab--auto .fb13-bell-icon,
.fb13-bell-badge--pulse { animation: none; }
.fb13-notif-panel { transition: none; }
} .fb13, .fb13 *, .fb13 *::before, .fb13 *::after { box-sizing: border-box; margin: 0; padding: 0; }
.fb13 {
font-family: 'Inter', sans-serif;
background: #0f172a;
min-height: 100vh;
display: grid;
place-items: center;
padding: 40px 20px;
color: #e2e8f0;
}
h1 {
font-size: clamp(1.6rem, 5vw, 2.4rem);
font-weight: 700;
text-align: center;
letter-spacing: -.022em;
margin-bottom: 8px;
}
p.fb13-sub {
text-align: center;
color: #475569;
font-size: .9rem;
max-width: 44ch;
margin: 0 auto 52px;
line-height: 1.6;
}
.fb13-scene {
width: min(780px, 100%);
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 20px;
}
.fb13-card {
background: #1e293b;
border: 1px solid #334155;
border-radius: 20px;
padding: 36px 24px;
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
position: relative;
overflow: hidden;
}
.fb13-card::before {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(ellipse 80% 60% at 50% -10%, rgba(99,102,241,.06), transparent);
pointer-events: none;
}
.fb13-card-tag {
font-size: .66rem;
font-weight: 600;
letter-spacing: .1em;
text-transform: uppercase;
color: #475569;
}
/* ── BELL FAB ── */
.fb13-bell-fab {
position: relative;
width: 66px;
height: 66px;
border-radius: 50%;
border: none;
cursor: pointer;
display: grid;
place-items: center;
outline: none;
transition: transform .22s cubic-bezier(.34,1.56,.64,1), box-shadow .2s;
}
/* Variant 1: Classic dark */
.fb13-bell-fab--dark {
background: #1e293b;
border: 1.5px solid #334155;
box-shadow: 0 4px 16px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.06);
}
.fb13-bell-fab--dark:hover {
transform: scale(1.1);
box-shadow: 0 8px 28px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.08);
border-color: #4f46e5;
}
/* Variant 2: Indigo filled */
.fb13-bell-fab--indigo {
background: linear-gradient(135deg, #6366f1, #4f46e5);
box-shadow: 0 6px 22px rgba(99,102,241,.45), inset 0 1px 0 rgba(255,255,255,.18);
}
.fb13-bell-fab--indigo:hover {
transform: scale(1.1);
box-shadow: 0 10px 32px rgba(99,102,241,.6), inset 0 1px 0 rgba(255,255,255,.2);
}
/* Variant 3: Amber alert */
.fb13-bell-fab--amber {
background: linear-gradient(135deg, #f59e0b, #d97706);
box-shadow: 0 6px 22px rgba(245,158,11,.45), inset 0 1px 0 rgba(255,255,255,.18);
}
.fb13-bell-fab--amber:hover {
transform: scale(1.1);
box-shadow: 0 10px 32px rgba(245,158,11,.6), inset 0 1px 0 rgba(255,255,255,.2);
}
/* Variant 4: Muted (no unread) */
.fb13-bell-fab--muted {
background: #1e293b;
border: 1.5px solid #2d3f55;
box-shadow: 0 2px 8px rgba(0,0,0,.4);
}
.fb13-bell-fab--muted:hover {
transform: scale(1.08);
border-color: #64748b;
}
/* bell icon */
.fb13-bell-fab svg.fb13-bell-icon {
width: 28px;
height: 28px;
position: relative;
z-index: 1;
}
.fb13-bell-fab--dark svg.fb13-bell-icon,
.fb13-bell-fab--muted svg.fb13-bell-icon { fill: #94a3b8; }
.fb13-bell-fab--indigo svg.fb13-bell-icon,
.fb13-bell-fab--amber svg.fb13-bell-icon { fill: #fff; }
/* bell ring animation */
@keyframes fb13-bell-ring {
0% { transform: rotate(0deg); }
10% { transform: rotate(12deg); }
20% { transform: rotate(-10deg); }
30% { transform: rotate(8deg); }
40% { transform: rotate(-6deg); }
50% { transform: rotate(4deg); }
60% { transform: rotate(-2deg); }
70% { transform: rotate(0deg); }
100% { transform: rotate(0deg); }
}
.fb13-bell-fab:hover .fb13-bell-icon,
.fb13-bell-fab:focus .fb13-bell-icon { animation: fb13-bell-ring .6s ease-in-out; }
.fb13-bell-fab--auto .fb13-bell-icon { animation: fb13-bell-ring 1s ease-in-out 1s infinite; animation-play-state: running; }
/* notification badge */
.fb13-bell-badge {
position: absolute;
top: 0;
right: 0;
min-width: 22px;
height: 22px;
border-radius: 11px;
background: #ef4444;
color: #fff;
font-size: .65rem;
font-weight: 700;
display: grid;
place-items: center;
padding: 0 5px;
border: 2.5px solid #0f172a;
z-index: 2;
transform: translate(4px, -4px);
animation: fb13-badge-in .4s cubic-bezier(.34,1.56,.64,1) both;
}
@keyframes fb13-badge-in {
from { transform: translate(4px,-4px) scale(0); }
to { transform: translate(4px,-4px) scale(1); }
}
/* pulsing badge */
.fb13-bell-badge--pulse { animation: fb13-badge-in .4s cubic-bezier(.34,1.56,.64,1) both, fb13-badge-pulse 2s ease-in-out 1s infinite; }
@keyframes fb13-badge-pulse {
0%,100% { box-shadow: 0 0 0 0 rgba(239,68,68,.5); }
50% { box-shadow: 0 0 0 6px rgba(239,68,68,0); }
}
/* dot badge (no number) */
.fb13-bell-badge--dot {
width: 13px;
height: 13px;
min-width: 0;
padding: 0;
border-radius: 50%;
background: #22c55e;
}
/* notification dropdown panel (for the JS variant) */
.fb13-notif-panel {
position: absolute;
top: calc(100% + 10px);
right: 0;
width: 280px;
background: #1e293b;
border: 1px solid #334155;
border-radius: 16px;
box-shadow: 0 16px 48px rgba(0,0,0,.6);
overflow: hidden;
opacity: 0;
transform: translateY(-8px) scale(.97);
pointer-events: none;
transform-origin: top right;
transition: opacity .25s ease, transform .28s cubic-bezier(.34,1.56,.64,1);
z-index: 20;
}
.fb13-notif-panel.fb13-open { opacity: 1; transform: none; pointer-events: auto; }
.fb13-np-header {
padding: 14px 16px;
border-bottom: 1px solid #334155;
display: flex;
align-items: center;
justify-content: space-between;
}
.fb13-np-header span { font-size: .8rem; font-weight: 600; color: #e2e8f0; }
.fb13-np-header small { font-size: .7rem; color: #6366f1; cursor: pointer; }
.fb13-np-item {
padding: 12px 16px;
border-bottom: 1px solid #1e293b;
display: flex;
gap: 10px;
cursor: pointer;
transition: background .1s;
}
.fb13-np-item:hover { background: #243449; }
.fb13-np-item:last-child { border: 0; }
.fb13-np-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; margin-top: 5px; }
.fb13-np-dot--blue { background: #6366f1; }
.fb13-np-dot--green { background: #22c55e; }
.fb13-np-dot--amber { background: #f59e0b; }
.fb13-np-dot--empty { background: transparent; border: 1px solid #334155; }
.fb13-np-text { font-size: .78rem; line-height: 1.4; }
.fb13-np-text strong { color: #e2e8f0; font-weight: 600; }
.fb13-np-text span { color: #64748b; }
.fb13-np-time { font-size: .66rem; color: #475569; margin-top: 3px; display: block; }
/* wrapper for interactive demo */
.fb13-interactive-wrap {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
}
@media (prefers-reduced-motion: reduce) {
.fb13-bell-fab svg.fb13-bell-icon,
.fb13-bell-fab--auto .fb13-bell-icon,
.fb13-bell-badge--pulse { animation: none; }
.fb13-notif-panel { transition: none; }
}const bell = document.getElementById('fb13-notif-bell');
const panel = document.getElementById('fb13-notif-panel');
const countBadge = document.getElementById('fb13-notif-count');
const markRead = document.getElementById('fb13-mark-read');
let open = false;
bell.addEventListener('click', () => {
open = !open;
panel.classList.toggle('fb13-open', open);
bell.setAttribute('aria-expanded', open);
});
document.addEventListener('click', e => {
if (!bell.contains(e.target) && !panel.contains(e.target)) {
open = false;
panel.classList.remove('fb13-open');
bell.setAttribute('aria-expanded', 'false');
}
});
markRead.addEventListener('click', e => {
e.stopPropagation();
countBadge.style.display = 'none';
document.querySelectorAll('.fb13-np-dot').forEach(d => d.className = 'fb13-np-dot fb13-np-dot--empty');
markRead.textContent = '✓ All read';
}); const bell = document.getElementById('fb13-notif-bell');
const panel = document.getElementById('fb13-notif-panel');
const countBadge = document.getElementById('fb13-notif-count');
const markRead = document.getElementById('fb13-mark-read');
let open = false;
bell.addEventListener('click', () => {
open = !open;
panel.classList.toggle('fb13-open', open);
bell.setAttribute('aria-expanded', open);
});
document.addEventListener('click', e => {
if (!bell.contains(e.target) && !panel.contains(e.target)) {
open = false;
panel.classList.remove('fb13-open');
bell.setAttribute('aria-expanded', 'false');
}
});
markRead.addEventListener('click', e => {
e.stopPropagation();
countBadge.style.display = 'none';
document.querySelectorAll('.fb13-np-dot').forEach(d => d.className = 'fb13-np-dot fb13-np-dot--empty');
markRead.textContent = '✓ All read';
});