Badge Dot Indicator — Free HTML CSS JS Notification Badge Snippet

Badge Dot Indicator · Misc · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Plain unread dot, numeric count badge, avatar status dot, and overflow-capped badge in one snippet
Absolute positioning anchored to a relatively-positioned icon or avatar parent
White/background border ring around each badge so it reads clearly against any icon color
Automatic "99+" overflow cap driven by a single MAX_DISPLAY constant
Badge auto-hides via display: none when the count reaches zero
min-width instead of a fixed width so both single digits and multi-character text render cleanly
Descriptive aria-label on icon buttons for screen reader users
Focus-visible outline on icon buttons for keyboard navigation

About this UI Snippet

Badge Dot Indicator — HTML, CSS & JavaScript Notification Badges

Screenshot of the Badge Dot Indicator snippet rendered live

A small colored dot or number in the corner of an icon is one of the most information-dense UI elements on the web — it tells the user "something happened here" without taking any extra space. This snippet demonstrates the three common variants: a plain unread dot on a bell icon, a numeric count badge on a messages icon, and an online-status dot on a circular avatar, plus a count badge that caps its display at "99+" once the real number gets too large to fit comfortably.

How the corner positioning works

Every badge is position: absolute inside a parent that has position: relative (the .icon-btn or .avatar). The dot variant uses top: 4px; right: 4px with a 2px white border, so it visually "cuts into" the icon's corner rather than floating in empty space outside it. The count variant is pulled slightly further outside the button with top: -6px; right: -6px, since it's wider than a plain dot and needs the extra clearance to avoid touching the icon glyph.

How the overflow cap works

Real unread counts can jump well past what fits legibly in an 18px circle. renderCount() compares count against a MAX_DISPLAY constant (99) and renders MAX_DISPLAY + '+' whenever the real count exceeds it, otherwise it renders the exact number. Because the badge uses min-width: 18px rather than a fixed width, both a single digit and "99+" render at a readable size without the circle becoming egg-shaped or the text overflowing its bounds.

How the badge auto-hides

When count reaches zero, renderCount() sets display: none on the badge so the icon reverts to its plain, unbadged state — there's no such thing as a "0" badge cluttering the UI.

Accessibility notes

Icon buttons carry a descriptive aria-label (e.g. "Messages, 5 unread") rather than relying on the badge's visual number alone, since screen readers do not reliably announce absolutely-positioned decorative badge text.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Give this snippet to an AI assistant and ask it to explain why the badge needs a border matching the page background rather than no border at all — the border is what visually separates the badge from the icon glyph underneath it and makes it read as "on top of" the icon rather than merging into it. It's also a good prompt for extending the pattern: ask the assistant to animate the badge with a brief scale-pulse whenever the count increases, or to add a small aria-live region so screen reader users are proactively notified when a new notification arrives rather than only on request.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a "badge dot indicator" set in plain HTML, CSS, and vanilla JavaScript covering these variants:

Requirements:
- A plain unread dot overlaying the top-right corner of an icon button, using absolute positioning anchored to a relatively-positioned parent, with a border matching the page background so it visually separates from the icon.
- A numeric count badge overlaying a second icon button, using min-width rather than a fixed width so it fits both single digits and multi-character text without clipping or looking oversized.
- A JavaScript overflow rule: once the underlying count exceeds a configurable maximum (default 99), the badge must display "99+" instead of the literal number, driven by a single named constant that is easy to change.
- A rule that hides the badge entirely (not just shows "0") whenever the underlying count is zero.
- A circular avatar with a small colored status dot in its corner to demonstrate the same technique used for presence indicators, not just notification counts.
- Every icon button must carry a descriptive aria-label reflecting both its purpose and its current badge state for screen reader users.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Load the snippetClick "Badge Dot Indicator" in the sidebar Library tab to see all four badge variants in the preview.
  2. 2
    Click "Add notification"Watch the count badge increase and eventually flip to the "99+" overflow state.
  3. 3
    Change the badge colorUpdate the background value on .badge-dot and .badge-count in the CSS panel to match your brand's alert color.
  4. 4
    Adjust the overflow thresholdChange the MAX_DISPLAY constant in the JS panel to cap the badge at a different number, like 9+ instead of 99+.
  5. 5
    Wire to real dataReplace the bumpCount demo function with a call that sets count from your actual unread/notification data and calls renderCount().
  6. 6
    Export and saveUse the export buttons or click "Save as" to keep a customized version for reuse.

Real-world uses

Common Use Cases

BELL
Notification bells and inboxes
Show an unread dot or exact count on a notification icon in an app header or nav bar.
CHAT
Messaging and chat unread counts
Display unread message counts on a chat icon, capping large numbers at "99+" to keep the badge compact.
AVATAR
Online/offline presence dots
Overlay a green or grey status dot on a user avatar to indicate presence in a team or chat app.
SHOP
Cart item counts
Show the number of items in a shopping cart icon, using the same overflow-safe count badge.
Dashboard alert indicators
Flag a sidebar icon (Settings, Billing) with a plain dot when something needs the user's attention.
Accessible badge patterns
Study how aria-label communicates badge information to screen readers instead of relying on visual-only text.

Got questions?

Frequently Asked Questions

A dot badge is a small solid circle that just signals "there is something new" without a specific number. A count badge shows the actual number of unread items, capping at a value like "99+" once the number gets too large to display cleanly.

The icon button or avatar has position: relative, and the badge has position: absolute with small top/right offsets. A visible border matching the page background creates the illusion the badge is cut into the icon rather than floating separately.

The renderCount function compares the live count against a MAX_DISPLAY constant (99). If count exceeds it, the badge renders "99+" instead of the literal number, keeping the badge width consistent and legible.

A fixed width would either clip "99+" or leave too much empty space around a single digit. min-width plus horizontal padding lets the badge grow just enough to fit its content while staying pill-shaped.

renderCount sets the badge's display to none whenever count is 0, so no empty circle is shown. Call renderCount whenever your underlying count changes.

Yes — the .avatar-dot variant is exactly that: a colored dot (green for online) placed in the corner of a circular avatar. Swap the color and update the aria-label to reflect the status text.

The visual badge alone is not reliably announced, so the icon button carries a full aria-label describing both the icon's purpose and its current count or status, e.g. "Messages, 5 unread".