Skip to content

Chat Bubbles with Typing Indicator

Pure CSS chat window with grouped incoming and outgoing message bubbles, an animated three-dot typing indicator and a working composer.

Also known as: messenger chat ui, chat bubbles, typing indicator animation, chat window mockup

Chat Bubbles with Typing Indicator live demo

Open in new tab

Pure CSS code (HTML, CSS, JS)

A chat window with incoming and outgoing message bubbles and an animated three-dot typing indicator, built with pure CSS and a few lines of vanilla JavaScript. Use it for support widgets, messenger mockups, onboarding demos or any page that needs a lively conversation preview.

How it works

The outer .tb-wrap paints the pastel gradient page and holds all custom properties. Inside it, section.tb-chat is a rounded card with three parts: the .tb-header (avatar with a green .tb-presence dot, name, the .tb-state line and a video call button), the scrollable .tb-body and the .tb-composer form.

Messages live in the ol.tb-log list. Each li.tb-msg gets .tb-msg--in or .tb-msg--out, which aligns it left or right. Incoming .tb-bubble elements use a soft lavender fill, outgoing ones a violet gradient, and one squared-off corner on each side acts as the tail. When the sender changes, an adjacent sibling selector adds extra space so messages read as groups. New messages fade in with the tb-pop keyframes.

The .tb-typing row sits under the log: a small avatar plus the .tb-dots bubble with three .tb-dot spans. They share the tb-bounce keyframes, and the second and third dots are delayed by a fraction of --tb-speed, which creates the wave. The indicator is pure CSS and shows on load.

The script runs on DOMContentLoaded for every .tb-chat. On submit it calls preventDefault(), appends your text as an outgoing bubble with the current time, scrolls .tb-body down and shows the indicator while .tb-state switches to "typing...". After REPLY_DELAY a reply from the REPLIES array is added and the indicator is hidden with the hidden attribute.

Customization

  • --tb-out-1 and --tb-out-2 on .tb-wrap: the gradient of outgoing bubbles, the send button and the typing status color.
  • --tb-in-bg: the background of incoming bubbles and the typing bubble.
  • --tb-dot-size, --tb-bounce and --tb-speed: the size of each dot, how high it jumps and the length of one wave.
  • --tb-radius: the roundness of all bubbles; the tail corner stays at 6px.
  • height of .tb-body: the visible message area, 340px on phones and 420px from 640px.
  • REPLY_DELAY and REPLIES in script.js: how long the indicator shows and the simulated answers. Replace the timeout with your WebSocket or server-sent events.

Use cases

  • Support widgets: incoming and outgoing bubbles show a live conversation with a typing indicator
  • Messenger mockups: grouped messages with timestamps look like a real chat app
  • Onboarding demos: a working composer adds your message and a simulated reply arrives
  • Landing pages: a presence dot and three-dot typing animation make the preview feel alive

Accessibility

The message list has role="log" with aria-live="polite", so new messages are announced. The typing row is a role="status" region with the visually hidden text "Maya is typing", while the dots are aria-hidden. The scroll area is focusable with an aria-label, the input has a hidden label, and icon buttons have aria-labels and a visible focus outline. With prefers-reduced-motion: reduce the bounce becomes a gentle opacity fade and the pop-in and smooth scrolling are turned off.

Usage notes

The avatar photo comes from Unsplash; replace it with your own image. The input id tb-input must be unique if you place two chats on one page.

Chat Bubbles with Typing Indicator at a glance

Framework
Pure CSS
Code
HTML, CSS, JavaScript
JavaScript
Vanilla JavaScript, no jQuery
Dependencies
None
Layout
Responsive, works on mobile
Category
Chat Widgets
License
Free for personal and commercial use

Questions about this template

Can I use the Chat Bubbles with Typing Indicator code for free?

Yes. You can copy or download the code and use it in personal and commercial projects, including client work. No sign-up is needed. Reselling it as part of a component library or template collection is not allowed; see the license.

How do I add it to my website?

There is nothing to install. Paste the HTML where the component should appear, add the CSS to your stylesheet and load the JavaScript before the closing </body> tag. Download HTML gives you a complete page with everything already linked.

Does it need jQuery or a JavaScript framework?

No. The script is plain vanilla JavaScript, so it works without jQuery, React or Vue. You can still use the markup inside those frameworks.

Does it work on mobile?

Yes. The layout adapts to small screens. Use the Mobile and Tablet buttons above the live demo to check it at phone and tablet width.

Requirements

No dependencies. Pure HTML, CSS and JavaScript.

Chat Bubbles with Typing Indicator – Pure CSS chat widgets component screenshot
Chat Bubbles with Typing Indicator · Pure CSS Chat Widgets

More Chat Widgets

Support Chat Popup with Agent Photo – Tailwind CSS chat widgets preview

Support Chat Popup with Agent Photo

Tailwind CSS support chat popup with an agent photo, online status dot, suggested questions, typing indicator, unread badge and simulated replies.

Chat Widget – Tailwind CSS chat widgets preview

Chat Widget

Tailwind CSS support chat widget with floating launcher, unread badge, message bubbles, suggested replies, typing indicator and Enter-to-send input.