Notification list
Category: Feedback · Tags: notifications, unread, inbox, mark-as-read, activity
Notifications
2 unread
-
Unread Amira Haddad commented on Q4 budget review.
-
Unread Your export of 1,240 contacts is ready to download.
-
Tomás Rivera added you to Website redesign.
How to use it
Use for an in-app list of recent notifications or activity where people need to tell new items from seen ones. Render the unread marker from your data and call your own API where the script marks items read. Make each notification a link to its subject if there is one; for a single transient confirmation use a toast instead.
Accessibility
The notifications are a <ul> under a heading; each unread item starts with the visible word "Unread" (plus bold text and an aria-hidden dot), so its state is read aloud and never shown by colour alone. "Mark all as read" is a native <button>; the unread count is a role="status" line, so the change to "No unread notifications" is announced while focus stays on the button, which then becomes aria-disabled. Item text #0f172a on #eff6ff (unread) and #ffffff is 16.4:1 and 17.9:1, times #475569 are 7.0:1 or more, and the "Unread" label is white on #1d4ed8 (6.7:1).
Source (copy-ready)
<section class="dcl-notiflist" aria-labelledby="dcl-notiflist-title">
<div class="dcl-notiflist__header">
<h3 class="dcl-notiflist__title" id="dcl-notiflist-title">Notifications</h3>
<button type="button" class="dcl-notiflist__markall">Mark all as read</button>
</div>
<p class="dcl-notiflist__count" role="status">2 unread</p>
<ul class="dcl-notiflist__list" role="list">
<li class="dcl-notiflist__item dcl-notiflist__item--unread">
<span class="dcl-notiflist__dot" aria-hidden="true"></span>
<div class="dcl-notiflist__body">
<p class="dcl-notiflist__text"><span class="dcl-notiflist__badge">Unread</span> Amira Haddad commented on <strong>Q4 budget review</strong>.</p>
<p class="dcl-notiflist__time"><time datetime="2026-11-06T13:48">12 minutes ago</time></p>
</div>
</li>
<li class="dcl-notiflist__item dcl-notiflist__item--unread">
<span class="dcl-notiflist__dot" aria-hidden="true"></span>
<div class="dcl-notiflist__body">
<p class="dcl-notiflist__text"><span class="dcl-notiflist__badge">Unread</span> Your export of 1,240 contacts is ready to download.</p>
<p class="dcl-notiflist__time"><time datetime="2026-11-06T11:05">3 hours ago</time></p>
</div>
</li>
<li class="dcl-notiflist__item">
<span class="dcl-notiflist__dot" aria-hidden="true"></span>
<div class="dcl-notiflist__body">
<p class="dcl-notiflist__text">Tomás Rivera added you to <strong>Website redesign</strong>.</p>
<p class="dcl-notiflist__time"><time datetime="2026-11-05T16:20">Yesterday</time></p>
</div>
</li>
</ul>
</section>
<style>
.dcl-notiflist { box-sizing: border-box; max-width: 30rem; border: 1px solid #e2e8f0; border-radius: 0.5rem; overflow: hidden; font: inherit; color: #0f172a; background-color: #ffffff; }
.dcl-notiflist__header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem; padding: 0.75rem 1rem 0; }
.dcl-notiflist__title { margin: 0; font-size: 1.125rem; color: #0f172a; background-color: #ffffff; }
.dcl-notiflist__markall { padding: 0.25rem 0.5rem; border: none; border-radius: 0.25rem; font: inherit; font-size: 0.875rem; font-weight: 600; text-decoration: underline; cursor: pointer; color: #1d4ed8; background-color: #ffffff; }
.dcl-notiflist__markall:hover { color: #1e3a8a; background-color: #eff6ff; }
.dcl-notiflist__markall:focus-visible { outline: 2px solid #1d4ed8; outline-offset: 2px; }
.dcl-notiflist__markall[aria-disabled="true"] { cursor: default; text-decoration: none; color: #475569; background-color: #ffffff; }
.dcl-notiflist__count { margin: 0.125rem 1rem 0.75rem; font-size: 0.875rem; color: #475569; background-color: #ffffff; }
.dcl-notiflist__list { margin: 0; padding: 0; list-style: none; }
.dcl-notiflist__item { display: flex; gap: 0.625rem; padding: 0.75rem 1rem; border-top: 1px solid #e2e8f0; color: #0f172a; background-color: #ffffff; }
.dcl-notiflist__item--unread { color: #0f172a; background-color: #eff6ff; }
.dcl-notiflist__dot { flex: none; width: 0.5rem; height: 0.5rem; margin-top: 0.5rem; border-radius: 50%; background-color: #cbd5e1; }
.dcl-notiflist__item--unread .dcl-notiflist__dot { background-color: #1d4ed8; }
.dcl-notiflist__body { min-width: 0; }
.dcl-notiflist__text { margin: 0; overflow-wrap: anywhere; }
.dcl-notiflist__item--unread .dcl-notiflist__text { font-weight: 600; }
.dcl-notiflist__badge { display: inline-block; margin-right: 0.25rem; padding: 0 0.375rem; border-radius: 0.25rem; font-size: 0.75rem; font-weight: 700; color: #ffffff; background-color: #1d4ed8; }
.dcl-notiflist__time { margin: 0.125rem 0 0; font-size: 0.8125rem; color: #475569; }
</style>
<script>
(function () {
document.querySelectorAll(".dcl-notiflist").forEach(function (root) {
if (root.dataset.dclBound) { return; }
root.dataset.dclBound = "true";
var markAll = root.querySelector(".dcl-notiflist__markall");
var count = root.querySelector(".dcl-notiflist__count");
if (!markAll) { return; }
markAll.addEventListener("click", function () {
if (markAll.getAttribute("aria-disabled") === "true") { return; }
/* Call your API here, then update the list. */
root.querySelectorAll(".dcl-notiflist__item--unread").forEach(function (item) {
item.classList.remove("dcl-notiflist__item--unread");
var badge = item.querySelector(".dcl-notiflist__badge");
if (badge) { badge.remove(); }
});
markAll.setAttribute("aria-disabled", "true");
if (count) { count.textContent = "No unread notifications"; }
});
});
})();
</script>
Was this useful? Send feedback.