Skip to content

Notification Dot and Count Badges

Pure CSS notification badges: count bubbles, 99+ pills, pulsing dots and status dots positioned on icon buttons, avatars and text buttons.

Pure CSS Badges Responsive Dark #avatar #badge #button #icon #notification

Live preview

Open in new tab

Code

A set of notification badges built with pure CSS: red count bubbles and small status dots pinned to the corner of icon buttons, avatars and text buttons. A few lines of vanilla JavaScript keep counts and labels in sync for app headers, inboxes and carts.

How it works

The root section.nb-showcase contains three .nb-panel cards. Every element that carries a badge (.nb-icon-btn, .nb-avatar, .nb-text-btn) is position: relative, so the absolutely positioned .nb-badge or .nb-dot sits on its top-right corner and is pushed half outside with transform: translate(35%, -35%). A box-shadow ring in the color of --nb-ring cuts the badge out of the button behind it.

.nb-badge uses min-width plus horizontal padding, so one digit gives a perfect circle and longer values such as 99+ grow into a pill. .nb-dot is a fixed-size circle; .nb-dot--pulse adds a ::after ring that scales and fades out to draw attention. .nb-dot--bottom moves the dot to the bottom-right corner for presence indicators (.nb-dot--online, .nb-dot--away, .nb-dot--busy), and .nb-dot--inline puts a small dot next to a label.

The script reads data-nb-count on each counted .nb-icon-btn. A click on that button resets the count to zero and hides the badge with .is-hidden (a scale-out transition). The demo button with data-nb-add adds one to the first counted button and replays a short bump animation. Counts above 99 are shown as 99+. Without JavaScript all badges are still displayed with their static values.

Customization

  • --nb-badge-bg and --nb-badge-text on .nb-showcase: the default badge color, e.g. an orange #f97316 for a softer alert style.
  • .nb-badge--blue and .nb-badge--violet: color modifiers that override --nb-badge-bg for a single badge; add your own in the same way.
  • --nb-badge-size and --nb-dot-size: the height of count badges and the diameter of dots, for larger touch targets or denser toolbars.
  • .nb-badge--top-left: moves a count badge to the opposite corner, as on the "DT" avatar.
  • --nb-ring: the cut-out ring color; set it to the background behind the button so the badge looks detached.
  • MAX in script.js: the cap above which a + is shown, e.g. 9 for a compact 9+.
  • data-nb-label on a button: the word used to build the updated aria-label, such as "Messages, 12 unread".

Accessibility

Visual badges are aria-hidden="true"; the meaning lives in the button's aria-label ("Notifications, 3 unread"), which the script rewrites whenever the count changes. Avatars use role="img" with a label that includes the status, and text buttons contain visually hidden .nb-sr text such as "unread" or "(new)". A polite aria-live region announces changes. All buttons and links have a clear :focus-visible outline in --nb-focus. With prefers-reduced-motion: reduce the pulse, bump and scale transitions are switched off.

Usage notes

The demo text and "Add notification" button are for the preview only. In a real app call your own code to set data-nb-count and the badge text when new data arrives. Several showcases can share one page because the script scopes each to its own root.

Requirements

No dependencies. Pure HTML, CSS and JavaScript.

Notification Dot and Count Badges – Pure CSS badges component screenshot
Notification Dot and Count Badges · Pure CSS Badges

More Badges

Dismissible Filter Chips – Bootstrap 5 badges preview

Dismissible Filter Chips

Bootstrap 5 active filter bar with removable chips, Clear all button, undo for recently removed filters and live result count.

Badges and Tags Collection – Tailwind CSS badges preview

Badges and Tags Collection

Dark Tailwind CSS badge collection: color pills, status dots, notification counters, icon badges and removable tags with an add-tag input.