Three dots at the end of text that doesn't fit is one of the most common layout requests there is: file names in a list, email subjects, product titles in a card. The CSS is three lines. Getting those three lines to actually work inside a real layout is the part that sends people searching.

Three dots CSS for one line of text

Here is the whole technique for a single line, built on the text-overflow property:

.truncate {
  white-space: nowrap;      /* keep the text on one line */
  overflow: hidden;         /* hide what doesn't fit */
  text-overflow: ellipsis;  /* show ... where it was cut */
}

All three are required, and each one fails silently without the others. text-overflow does nothing on its own, because by default text wraps instead of overflowing. The element also needs a width limit the text exceeds, whether that is a fixed width, a max-width, or its parent's size, and it has to be a block or inline-block element. On a plain inline <span> it never triggers.

Why it breaks inside flexbox

The classic layout: a row with a label that should shrink and truncate on the left, and something fixed on the right, a date or a button. Drag the bottom-right corner of the box below to resize it:

quarterly-infrastructure-cost-report-final-v3-reviewed.pdf 2.4 MB

You would expect the truncate class on the left item to be enough. It usually isn't, and the reason is one of the least obvious defaults in CSS: flex items have min-width: auto. A flex item refuses to shrink below the width of its content, so the long file name pushes the row wider instead of overflowing, and the ellipsis never appears.

The fix is one line:

.row {
  display: flex;
  align-items: center;
  gap: 12px;
}

.row .name {
  flex: 1 1 auto;   /* take the free space, allow shrinking */
  min-width: 0;     /* the line everyone forgets */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.row .size {
  flex: 0 0 auto;   /* never grow, never shrink */
}
<div class="row">
  <span class="name">quarterly-infrastructure-cost-report-final-v3-reviewed.pdf</span>
  <span class="size">2.4 MB</span>
</div>

Technically overflow: hidden alone also resets the automatic minimum, which is why some snippets work without min-width: 0. The trouble starts when the text sits one level deeper, inside a wrapper element. Then the wrapper is the flex item, it still has min-width: auto, and it needs min-width: 0 even though the truncation styles live on its child. If truncation mysteriously fails, walk up the tree and add min-width: 0 to every flex item between the text and the row.

flex: 0 0 auto on the right-hand item is what keeps the size label from being squeezed or wrapped when space runs out.

CSS 3 dots after two or three lines

text-overflow only works on a single line. For card descriptions and previews that should show two or three lines and then cut off, use line clamping:

.clamp-3 {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
}

Yes, it still uses -webkit- prefixed properties, and yes, it works in every current browser including Firefox. The standard line-clamp property is defined in CSS Overflow Level 4, and browser support for the unprefixed version is still settling, so declare both. Check caniuse for line-clamp if you need to know the state today.

Do not add white-space: nowrap here. It collapses everything back onto one line and the clamp has nothing to count.

Table cells and grids

Tables have their own version of the flexbox problem: by default a column grows to fit its longest content. Fix the table's layout so columns respect the widths you give them:

table.files {
  width: 100%;
  table-layout: fixed;
}

table.files td.name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

CSS Grid behaves like flexbox. A 1fr track has an automatic minimum as well, so long text blows the column open. Use minmax(0, 1fr) for the column, or min-width: 0 on the grid item:

.card-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

Letting people read the full text

Truncation hides information, so give people a way to get it back. The cheapest option is the full string in a title attribute, which shows as a native tooltip on hover:

<span class="name" title="quarterly-infrastructure-cost-report-final-v3-reviewed.pdf">
  quarterly-infrastructure-cost-report-final-v3-reviewed.pdf
</span>

Tooltips don't exist on touch screens, though. On mobile, the better pattern is to let a tap remove the truncation class and show the full text in place.

Screen readers see the whole text

CSS truncation is purely visual. Screen readers still read the full string, which is usually what you want. The reverse is not true: if you shorten text in JavaScript and add the dots yourself, assistive technology only gets the shortened version, so keep the full text in an aria-label or the title.

HTML 3 dots: three-dot icons and codes

Some people searching for "css three dots" want the icon, not the truncation. You don't need an icon font for it:

Character HTML code Typical use
&hellip; or &#8230; Ellipsis in text
&#8942; Vertical "more" menu (kebab)
&#8943; Horizontal "more" menu (meatball)
<button class="menu-button" aria-label="More options">&#8942;</button>

The aria-label is not optional. A button whose only content is a symbol is announced as nothing useful without it. The same goes for custom media controls; if you replace a video player's native buttons, hiding HTML5 video controls covers the CSS side of that.

If you build interfaces for video calls, the same truncation problem shows up constantly in participant lists and tile name labels. Customizing the Jitsi Meet front end covers where those styles live, and the Jitsi Meet IFrame API is the route if you are embedding meetings inside your own layout. For responsive layouts more generally, the key elements of responsive web design goes through the building blocks.

Frequently Asked Questions

Why is text-overflow: ellipsis not working?

It needs three things together: overflow: hidden, white-space: nowrap, and a width limit the text actually exceeds. It also only applies to block or inline-block elements. Inside a flex or grid layout, the item usually also needs min-width: 0, or it grows to fit the text and never overflows.

How do I add 3 dots in CSS?

Put white-space: nowrap, overflow: hidden and text-overflow: ellipsis on an element with a width limit. The browser cuts the text where it overflows and draws three dots. Inside flexbox, also add min-width: 0 to the flex item.

How do I add three dots after two or three lines of text?

Use line clamping: display: -webkit-box, -webkit-box-orient: vertical, -webkit-line-clamp set to the number of lines, and overflow: hidden. Add the standard line-clamp property next to it so the rule keeps working as browsers adopt the unprefixed version.

Can CSS put the ellipsis in the middle of the text?

No. CSS only truncates at the end (or the start, with direction tricks). For middle truncation, such as long file names where the extension must stay visible, split the string in JavaScript or render the start and end in two elements.

How do I show the full text when it is truncated?

The simplest option is a title attribute with the full string, which gives a native tooltip on hover. For touch devices, where hover does not exist, let a tap expand the element by removing the truncation class.

What is the HTML code for three dots?

… or … is the horizontal ellipsis character. For a vertical three-dot menu icon use ⋮, and for a horizontal one use ⋯. Give icon-only buttons an aria-label so screen readers announce what they do.