A CSS speech bubble generator example produces a rounded message surface and a triangular pointer from a single base class plus an absolutely positioned ::after pseudo-element, and it does so without images or SVG. The core input set stays narrow on purpose: two six-digit hex colors for the bubble and text, a corner radius from 0 to 80 pixels, a tail size from 4 to 40 pixels, and one of four fixed tail directions. Internally, every tail is drawn as a zero-width, zero-height box whose borders meet at 45-degree angles; the two borders flanking the chosen side are made transparent while the border on the opposite side is painted in the bubble color, and the resulting triangle is then centered against the side it points from. The visible preview and the copied code share the same validated size, color, side, and offset, so the shape you see is the shape you paste.

How the Input Controls Become Triangle Borders
The CSS Speech Bubble Generator exposes four practical numeric or color controls and one of four tail sides. Each control maps to a deliberate, inspectable CSS declaration so the geometry stays understandable when you open browser developer tools.
The triangle technique is documented in detail on MDN's border-style reference and in the W3C CSS Backgrounds and Borders Level 3 specification. The short version is that an element with zero width and zero height produces four triangular border regions that meet at 45-degree angles. Coloring only the border opposite the chosen tail direction yields an arrowhead; the two transparent neighbors become the triangle's other two sides, and their width defines the triangle's base.
| Tail side | Colored border | Transparent borders | Anchored against |
|---|---|---|---|
| Top | Bottom | Left, Right | Top edge of the bubble, centered |
| Right | Left | Top, Bottom | Right edge of the bubble, centered |
| Bottom | Top | Left, Right | Bottom edge of the bubble, centered |
| Left | Right | Top, Bottom | Left edge of the bubble, centered |
Because pseudo-elements cannot be targeted by inline styles, the preview area draws the same geometry as a real child element. The copied production rule expresses the same shape as a ::after pseudo-element attached to the base class, which is why the preview and the paste are visually identical without any markup change in the page itself. A more compact recap of the border math is collected in the CSS Speech Bubble Generator Cheat Sheet: Borders and Tails guide.
Build One Bubble From Inputs to CSS
The exact workflow the CSS Speech Bubble Generator is built for, using concrete values that you can drop into a chat message mockup:
- Pick the bubble and text colors. Use complete six-digit hexadecimal values that together give readable text. For this example, set the bubble to #2563eb and the text to #ffffff.
- Set the corner radius and the triangle tail size. For this example, set the radius to 16 px and the tail size to 16 px.
- Choose the tail side. For this example, pick bottom so the pointer sits under the message, the position most chat interfaces use.
- Inspect the live preview. The triangle should be centered against the bottom edge and match the bubble color exactly, with no visible misalignment between the bubble border and the triangle base.
- Copy the CSS. Paste the base class and the ::after rule into your stylesheet next to the component that owns the bubble.
- Adjust the fifty-percent position if the pointer should align with an avatar or any anchor other than the center.
That is the entire production path for the geometry itself. Width, padding, typography, focus behavior, and animation logic are intentionally left out so the copied block stays narrow and predictable across components.
The CSS the Generator Emits
The output is two declarations: a class for the bubble shape and a pseudo-element rule for the triangle. With the example values above, the copied block has the same structure regardless of which side you choose — only the colored border and the positioning offset change.
The bubble class receives position: relative so the triangle can anchor against it, the validated border-radius, and the bubble and text color pair. The pseudo-element rule positions the triangle absolutely, drops a solid transparent border of the requested tail size on every side, and paints just one of those borders — border-top-color in the example — with the bubble color. Width is zero and height is zero so the colored border alone produces the arrowhead.
For a top tail, border-bottom-color is the colored one and the absolute positioning anchors against the top of the bubble. For right and left tails, the transparent borders are top and bottom while the colored border faces inward, and the positioning offset shifts to top: 50%; left: 100% or its mirror. The CSS Speech Bubble Generator writes those declarations explicitly so the geometry remains inspectable, and the side choice is the only variable between configurations.
Integrating the Bubble Into a Real Layout
A bubble is a shape, not a UI component. Once the geometry is on the page, the next decisions are semantic and contextual.
For a chat message, wrap the bubble in a list item inside a container that exposes the author and a timestamp. Expose status and order in plain text rather than encoding them only through left or right placement, because a decorative pointer does not establish a semantic relationship and screen reader users should still be able to follow who said what and when. For a quoted pull quote, a <blockquote> or a simple <p> is the right wrapper. For an interactive tooltip, the shape alone is not enough — add the trigger association, keyboard reachability, predictable dismissal, focus behavior, and an accessible name, then verify each in a real browser session before shipping.
Give the production component a sensible maximum width, padding, and wrapping rules before dropping it into a column. Long unbroken strings, narrow mobile widths, zoom, and translated copy can all expand the box unexpectedly and collide with the tail. Reserve enough outer space on the selected tail side and inspect every responsive breakpoint, not just the desktop width.
If the bubble sits inside an ancestor with overflow: hidden or another clipped container, the pointer can be sliced off. The most common cause is a parent that does not expect decorative children poking past its bounds. Inspect the chain of containing blocks, then either move the bubble or relax the clip. The same risk applies to viewports with content cut off by a fixed header or a sticky toolbar.
Contrast is a separate problem. The generator accepts any valid pair of six-digit colors, so a visually pleasing bubble can still be unreadable. The tool does not calculate WCAG ratios; that check belongs in your own stylesheet pass with a contrast reference that accounts for the actual rendered text size and weight.
Limits and What the Generator Refuses
The validation rules inside the CSS Speech Bubble Generator are deliberately narrow, and they define what you can paste into production:
- Tail size is bounded between 4 px and 40 px. Outside that range, the geometry stops reading as a pointer.
- Corner radius is bounded between 0 px and 80 px. Larger values force the bubble into a stadium or pill that no longer reads as a message.
- Colors must be complete six-digit hexadecimal values such as #2563eb. Short forms and named colors are rejected by design.
- Empty numeric controls are rejected rather than converted to zero. Empty numeric fields are rejected rather than converted to zero.
Tail size also bounds the triangle base. With the bordered-triangle technique, the base equals twice the tail size, so the working formula is triangle base = 2 × tail size. Substituting the example values gives 2 × 16 px = 32 px, which is the width of the triangle drawn against the bubble's bottom edge. That relationship is why a tiny tail produces a barely visible pointer and a large tail produces a substantial wedge.
The four tail directions are exhaustive. Custom offsets, multiple pointers, curved tails, outlines, and drop shadows are intentionally outside this focused output. If your design needs them, layer them on after copying — the generator stops where the shape stops and leaves the rest to your own component code.
Where the Calculation Happens
Every calculation runs locally in the browser. Nothing is uploaded, nothing is retained, no account is needed, and no new dependency is added to the page. The same validated size, color, side, and offset drive both the visible preview and the copied rule, so the preview is a faithful proxy for the final output.
Because both paths reuse the same formula, the geometry you see is exactly the geometry you paste. That makes reviewer handoff cleaner — a designer can capture a specific configuration, send the CSS, and the integrator gets the same shape without re-deriving border math from a screenshot. After copying, the work that remains is integrating existing tokens, testing semantic reading order, keyboard behavior where relevant, contrast, high-contrast modes, zoom, localization, overflow, and the exact container that will host the pointer.
If you're weighing options, CSS Stripes Generator: Command Line vs Online covers this in detail.