To cut text off after a set number of lines, put four declarations on the element: display: -webkit-box, -webkit-box-orient: vertical, -webkit-line-clamp: N and overflow: hidden. That is the whole technique. Most of the trouble people run into comes from the code around it: padding, flex layouts and rules that override display. This guide covers which truncation method to pick, how to fix the failures, and how to add a Read more button that only appears when text is really cut.

The Quick Answer

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

Change the number to change the line count. To preview different line counts and copy the output as CSS or Tailwind, use the CSS Line Clamp Generator.

Which Truncation Method Should You Use?

Line clamp is not the only way to shorten text, and it is not always the best one. Match the method to the job:

MethodBest forLimitation
line-clampTwo to six line previews in cards, lists and feedsCounts lines only, and needs the -webkit-box display mode
Single-line ellipsisTitles, table cells, breadcrumbs, filenamesOne line only
max-height with overflow hiddenFixed-height panelsCuts through the middle of a line and shows no ellipsis
Fade-out overlayLong text where a hard cut looks harshNeeds a background color that matches the overlay
JavaScript truncationCutting at a character count or word boundaryRuns after load, can shift the layout, and may remove text from the markup
Rule of thumb: Use single-line ellipsis for labels, line-clamp for previews, and a fade-out when the content is long and the container height is fixed.

Why Line Clamp Fails (and How to Fix It)

1. Extra text shows below the last line

Overflow is clipped at the padding edge, not the content edge. If the clamped element has bottom padding, the start of the next line can show inside that padding. Move the padding to a wrapper and keep the clamp on the inner element.

/* Problem: padding on the clamped element */
.card-text {
  -webkit-line-clamp: 3;
  padding: 12px;
}

/* Fix: padding on a wrapper, clamp on the text */
.card-body {
  padding: 12px;
}
.card-text {
  -webkit-line-clamp: 3;
}

2. The clamp does nothing

Another rule is changing display on the same element. A utility class, a media query or a later rule that sets display: flex, grid or block replaces -webkit-box, and the clamp is ignored.

Check this first: Inspect the element in DevTools and read the computed display value. If it says block, flex or grid instead of -webkit-box, something is overriding your clamp.

3. Long URLs or IDs push a flex item wider

A flex item will not shrink below its content width by default, and a long unbroken string cannot wrap. Allow the item to shrink and let the string break:

.card-text {
  min-width: 0;
  overflow-wrap: anywhere;
}

Add a Read More Toggle

Line clamp hides the rest of the text, so readers need a way to see it. The check scrollHeight > clientHeight tells you whether text is actually being cut. Use it to show the button only when it is needed, and set aria-expanded so assistive technology knows the state. Try it below, then resize your window to see the button come and go.

Wireless Headphones

Industry-leading noise cancellation, a 30-hour battery and a comfortable over-ear fit built for all-day listening. The ear cushions use memory foam, the headband folds flat for travel, and a quick-charge mode gives you five hours of playback from a ten minute charge.

.demo-text {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}
.demo-text.open {
  -webkit-line-clamp: none;
  line-clamp: none;
}
const text = document.querySelector('.demo-text');
const btn = document.querySelector('.demo-toggle');

btn.hidden = !(text.scrollHeight > text.clientHeight);

btn.addEventListener('click', () => {
  const open = text.classList.toggle('open');
  btn.textContent = open ? 'Show less' : 'Read more';
  btn.setAttribute('aria-expanded', String(open));
});

A Fade-Out Alternative

When the container has a fixed height, a gradient fade often looks better than a hard ellipsis. Use max-height for the cut and an ::after overlay for the fade. The gradient must end in the same color as the card background.

.fade-text {
  position: relative;
  max-height: 4.8em;
  line-height: 1.6;
  overflow: hidden;
}
.fade-text::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 1.6em;
  background: linear-gradient(to bottom, transparent, #1a1d27);
}

If you are new to pseudo-elements, the CSS Before and After guide explains how ::after works.

Line Clamp in Tailwind CSS

The same padding problem applies. Putting p-3 and line-clamp-3 on one element lets the next line show, so wrap the text:

<div class="p-3">
  <p class="line-clamp-3">...</p>
</div>

If your project still lists the old @tailwindcss/line-clamp plugin, you can remove it from package.json and from the plugins array in your Tailwind config. The utilities have been part of Tailwind core since v3.3, and the class names stay the same, so no markup changes are needed.

Accessibility Notes

  • Clamped text is hidden visually only. Screen readers still read the full text, so the experience differs from what sighted users see.
  • Do not clamp information people need to act on, such as prices, error messages or deadlines.
  • Offer a way to reach the full text, such as the Read more toggle above, instead of relying on a title tooltip, which touch screens do not show.

Browser Support

The prefixed -webkit-line-clamp works across the current major browsers and is the version to ship. MDN lists the unprefixed line-clamp property as limited availability, so keep both in the same rule, as the quick answer does. Support changes, so check caniuse or MDN before relying on the unprefixed form alone.

Frequently Asked Questions

How can I truncate text after 3 lines in CSS?

Put display: -webkit-box, -webkit-box-orient: vertical, -webkit-line-clamp: 3 and overflow: hidden on the element. Change the 3 to any other number to change how many lines stay visible.

How do I truncate text in CSS?

It depends on the number of lines. For one line, use white-space: nowrap, overflow: hidden and text-overflow: ellipsis on an element with a limited width. For two or more lines, use line-clamp.

How can I restrict text to one line using CSS?

Use white-space: nowrap to stop the text from wrapping. Add overflow: hidden and text-overflow: ellipsis so a long string is cut with an ellipsis instead of running past its box. Inside a flex item, also add min-width: 0 so the item is allowed to shrink.

How do I trim text in CSS?

CSS cannot change the text itself, it only controls how much of it is visible. Properties like text-overflow and line-clamp hide the extra text visually while the full string stays in the page. To actually remove characters or whitespace, use JavaScript methods such as slice() and trim(), or trim the text on the server.

Is line-clamp the same as the CSS clamp() function?

No. line-clamp limits how many lines of text are shown. The clamp() function takes a minimum, a preferred value and a maximum, and is used for sizes such as fluid font-size values, for example clamp(1rem, 2.5vw, 2rem).

Why does line-clamp show extra text below the last line?

Padding on the clamped element is the usual cause. Overflow is clipped at the padding edge, so the padding area leaves room for part of the next line to show. Move the padding to a wrapper element and keep the clamp on the inner text element.

Tune your line clamp visually

Set the line count, preview it on a card, excerpt or comment, and copy CSS or Tailwind output instantly.

Try the Line Clamp Generator