For years, developers have relied on hacky and hybrid approaches to truncating text on the Web. Most developers still consider using JavaScript for that and are unaware of the modern CSS text truncation solutions that don’t require JavaScript.
In this article, we’ll learn how to truncate text with three dots in CSS. We’ll use two reliable CSS text truncation techniques while covering single-line and multi-line truncations. Additionally, we’ll take some of these solutions a step further to implement practical use cases in front-end Web development.
The only prerequisite for this tutorial is working knowledge of HTML and CSS. Knowing some JavaScript would be a plus for exploring practical use cases.
white-space: nowrap
, clip it with overflow: hidden
text-overflow: ellipsis
property for smart text truncation with an automatic ellipsis indicatoroverflow: hidden
, and use -webkit-line-clamp
to define the number of lines till the text should be shown
-webkit-box
) and a vertical -webkit-box-orient
property, since line-clamping in CSS isn’t yet standardized and still relies on a preceding WebKit mechanism to function properlyIf you are in a hurry, copy and paste this CSS snippet, apply the mentioned CSS class to your HTML element, and you’re done! Quick text truncation with pure CSS; no JavaScript needed!:
.truncated-text { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
Editor’s note: This post was updated by Rahul Chhodde in June 2025 to focus primarily on truncating text in CSS (not JavaScript), expand and modernize browser notes, and add visual demos via CodePen.
Truncating text is a common problem that front-end developers encounter, especially when creating content-rich user interfaces.
Text truncation, in brief, is the process of shortening a given text segment to a specified length to meet UI needs while indicating truncation with a symbol, which is mostly an ellipsis (…).
With varying screen or container sizes, these UI needs could be:
Note that text truncation is different from text trimming.
Trimming removes whitespace from a given string of text, whereas truncation shortens the text while displaying a truncation indicator at the end of the shortened text:
On the Web, trimming is generally performed using JavaScript by modifying a given piece of text in the DOM, which often ends up mutating the original text. This is acceptable since we don’t remove any crucial information during this manipulation, only whitespace.
When truncating text with JavaScript, removing certain parts of the text may result in losing crucial information, which is considered bad from a UX viewpoint. This problem certainly has workarounds, but we don’t need them if truncating text remains on the presentation side of things using CSS, where the text is not originally modified, but rather styled to look shorter.
In the upcoming sections, we’ll explore techniques for truncating text with CSS without affecting its accessibility and originality.
If your app targets older browsers, CSS pseudo-elements enable you to implement makeshift text truncation that works on both modern and legacy browsers.
The structure should be simple so that the idea can be implemented with any element later on. Let’s begin with the starting markup:
<div class="container"> <p class="truncated-text">...</p> </div>
Here’s a rough idea about how to truncate text with CSS pseudo-elements:
white-space
CSS property and force it to be contained in a single line without wrapping to the next lineoverflow
CSS property so that its parent maintains its original widthTaking this idea to the code, here’s the initial CSS setup:
.container { --container-bg-color: white; background-color: var(--container-bg-color); } .truncated-text { position: relative; white-space: nowrap; overflow: hidden; } .truncated-text::after { position: absolute; right: 0; content: "\2026"; background-color: var(--container-bg-color); }
In the above code, we added an ellipsis symbol to any element that carries the truncated-text
CSS class, provided it with the background color of the container for contrast, and positioned it to the absolute right of the corresponding text using the CSS position property.
In the above code, \2026
is the Unicode escape sequence for the horizontal ellipsis character. Such escape sequences are typically used with the content
property to obtain generated content in CSS for consistent rendering across platforms with different file encodings:
See the Pen
Clipping text with CSS by Rahul (@c99rahul)
on CodePen.
If you resize the container division of the clipped text in the above demo, you’ll notice that the ellipsis symbol stays visible even when there is enough space for our text to display.
To fix that, instead of adding an ellipsis symbol, we can add a gradient background to the pseudo-element that fades in and matches the background color of the parent container, creating an indicator for the user to identify the truncation:
.truncated-text::after { content: ""; position: absolute; top: 0; right: 0; display: block; width: 2em; height: 100%; }
With this approach, our truncation indicator will neatly blend into the main container’s background whenever sufficient space is available for the corresponding text to appear:
See the Pen
Truncating text with CSS pseudo-elements by Rahul (@c99rahul)
on CodePen.
This technique won’t affect the accessibility at all, but it has its trade-offs. It makes you reliant on the parent’s background color, the truncation indication isn’t commonly recognized, and it doesn’t support multi-line truncation.
text-overflow
to truncate textCSS Overflow Module Level 3 introduced the text-overflow
property, which allows you to define the clipping methods for a given text segment.
This property supports two types of text overflows: clip and ellipsis. We have clip
as the default value for text-overflow
, which specifies normal clipping for the text. In contrast, setting text-overflow
to ellipsis adds an ellipsis symbol at the end of the clipped text.
This makes text truncation a matter of a few lines of CSS. Here are five lines of CSS to quickly obtain single-line truncation with text-overflow
:
.truncated-text { white-space: nowrap; overflow: hidden; text-overflow: ellipses; }
Following the last example, we performed the following operations on any HTML element that carries a truncated-text
CSS class:
text-overflow
property to bring about the text truncation effectIt’s worth noting that single-line and even multi-line truncations of text elements always depend on the width of their parent container. If the container provides enough space to fit the text in a single line, the text will display as is without truncating.
Here’s a simple demo depicting the same, where a 450-pixel-wide card container makes use of our CSS-based text-truncation setup:
See the Pen
Single-line text-clipping with CSS (with ellipsis) by Rahul (@c99rahul)
on CodePen.
Try resizing the card element using the resize notch at the bottom-right corner in the demo to experience the smart text truncation, powered by the text-overflow
property.
Tailwind CSS offers overflow-ellipsis
CSS class to implement the above-discussed text clipping in a utility-based CSS approach. We can pair it with whitespace-nowrap
and overflow-hidden
classes to achieve the steps necessary for the text-truncation effect we covered above:
<p class="whitespace-nowrap overflow-hidden text-ellipsis"> <!-- Add text that you want to appear shortened/truncated --> </p>
See the Pen
Single-line text-clipping with CSS (with ellipsis TWCSS) by Rahul (@c99rahul)
on CodePen.
text-overflow
in a flexboxIf declaring text-overflow: ellipsis
is not working inside a flexbox child element and it appears oversized, breaking the flow of the container, it is likely due to the default auto min-width
of flexbox children.
This default auto min-width
of flexbox children prevents them from shrinking below the width acquired by their contents; therefore, the required width to clip the text and show ellipses with text-overflow
is never achieved.
This weird layout behaviour can be fixed by providing any min-width
value other than auto
to the flexbox child containing the truncated text:
.card { display: flex; } .card-content { min-width: 0; /* Applying some min-width fixes the issue of oversizing */ }
See the Pen
Single-line text truncation Flexbox issue by Rahul (@c99rahul)
on CodePen.
The text-overflow
property doesn’t allow us to define the length of our text; it just specifies a clipping style for the text and creates a single-line truncated text effect when applied to unwrapped text.
For multi-line truncation, we have the line-clamp
property, which is not yet standardized; however, it allows us to specify lines that limit the content of a given text block on certain modern browsers without requiring JavaScript.
With line-clamp
, we don’t have to unwrap the text as we did in previous examples. Instead, we have to pair it with a couple more properties, as shown below:
.truncated-text { overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
In the above block of CSS, we are doing the following three things:
-webkit-line-clamp
overflow
property-webkit-box
display and a vertical -webkit-box-orient
Here’s how this should render on supporting browsers:
See the Pen
Multi-line text truncation with CSS by Rahul (@c99rahul)
on CodePen.
Tailwind CSS provides line-clamp-<number>
utility classes with predefined as well as arbitrary sizing. Here’s how you can establish the above-mentioned truncation effect with Tailwind CSS utility classes:
<p class="line-clamp-2"> <!-- Add text that you want to appear shortened/truncated. Make sure it's a bit longer to have multi-line truncation visible. --> </p>
See the Pen
Multi-line text-clipping with Tailwind CSS by Rahul (@c99rahul)
on CodePen.
line-clamp
As discussed, the line-clamp
property itself is not yet standardized; you must specify certain WebKit-specific properties to ensure things work as expected. It has good support, and including the WebKit workaround, nearly 96% of browsers are compatible with it.
The CSS line-clamping is likely to receive a standardized property soon that would eliminate the need for the above-mentioned WebKit-specific properties. Check the support updates here.
If you are still looking for a fallback, pair this strategy with a JavaScript solution like CuttrJS and test the support for the -webkit-line-clamp
property with the CSS.supports
object as shown below:
// Check if line-clamp is supported using CSS.supports() if (!CSS.supports('-webkit-line-clamp', '1')) { document.body.classList.add('no-line-clamp'); // Apply Cuttr.js to all .truncate elements document.querySelectorAll('.truncated-text').forEach(el => { new Cuttr(el, { truncate: 'words', length: 30, ending: '...' }); }); }
Here’s a revised example that uses our line-clamp setup with a fallback to a JavaScript workaround that utilizes the CuttrJS library. If the browser doesn’t support the property, the code plugs in a JavaScript solution to truncate the text in question:
See the Pen
Multi-line text-clipping with JavaScript by Rahul (@c99rahul)
on CodePen.
WCAG emphasizes that Web content should be perceivable, operable, understandable, and robust to be accessible to everyone.
Perceivability and understandability of the content rely completely on the creator, while the operability and robustness are where the technical implementation comes into play.
Truncations that involve mutation of the original text in the DOM may hinder the operability and robustness of the content, and hence may spoil the experience for users with disabilities if no cues to the full text are provided in the markup through ARIA attributes.
The video below shows this issue in action with its solution, where the generic text truncation with JavaScript is fixed by adding an aria-label
attributed after failing to be read by the screen reader
As established in the test above, if you prefer to go the JavaScript way, make sure you add an aria-label
attribute to the text element that is to undergo truncation with the original or shorter, alternative version of the original text as its value. This way, screen readers will be able to read the required information to users with disabilities:
<p class="truncated-text" aria-label="Accessible text-truncation with ARIA"> Accessible text-truncation with ARIA </p>
Since CSS truncation shortens the text on the presentational side only, no textual content in the DOM undergoes modification. Therefore, screen readers read the original text data from the DOM for truncated text without problem, which means you don’t have to describe the truncation using an ARIA attribute in this case.
This concludes that there are no potential accessibility implications with a CSS-based text truncation strategy, which is proven by this accessibility test for one of the demos we covered above in the article.
However, even if it’s presentational, text truncation can still impose some cognitive load on normal users as it requires them to infer the original meaning of the content. The simplest way to lower that load is by providing a shorter version of the original text in the title
attribute for that text fragment.
Another popular approach to reducing the cognitive load caused by text truncation is to switch the truncation on and off with a button, which requires a little bit of JavaScript for toggling the CSS classes in the DOM.
You may opt for any user event to toggle the CSS-based text truncation, let’s say, hover or focus. However, the most sane way here is to ask the user to read more of the truncated text by clicking a button.
Here’s the starter markup where truncated-text
CSS class is at work as discussed in earlier examples:
<div class="..."> <p class="truncated-text">...</p> <button class="..." onclick="toggleText(this)" data-collapsed-text="Read more +" data-expanded-text="Show less -" >Read more +</button> </div>
With the previous setup, we are adding a toggle button beneath the truncated text, and providing it with some attributes like:
onclick
— To use a toggle function (toggleText) on button click, which we will be defining nextdata-collapsed-text
and data-expanded-text
— To supply the button with a suitable label according to the truncation stateTo set up this on-demand toggling of text-truncation that we have already established with CSS, we can write a simple JavaScript function as shown below:
function toggleText(button) { const target = button.previousElementSibling; target.classList.toggle("truncated-text"); const isCollapsed = target.classList.contains("truncated-text"); const collapsedText = button.dataset.collapsedText; const expandedText = button.dataset.expandedText; button.textContent = isCollapsed ? collapsedText : expandedText; }
The above code is achieving the following things:
toggleText
functionSee the Pen
Toggling CSS text truncation on button click by Rahul (@c99rahul)
on CodePen.
Also see the React version of the above implementation.
Unlike some ready-made JavaScript solutions for text truncation, this small workaround is completely accessible. I’ve kept this as bloat-free, performant, accessible, and minimal as possible, which is not always the case when using a ready-made library or package.
I invite you to test it in terms of accessibility and further improve it to adopt in one of your projects. You may find all of the examples covered here (and some bonus ones) in this Codepen collection.
Throughout the article, we reviewed how to truncate text in CSS using CSS-only methods and also paired them with JavaScript techniques for better use cases. Besides the nuances of text truncation, we also learned about some WCAG principles and guidelines to ensure content accessibility and usability.
In the hope that you learned something new from this article, I would be delighted to know your thoughts and suggestions in the comments. Feel free to share your questions as well if you felt stuck at any point during the tutorial.
As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.
LogRocket lets you replay user sessions, eliminating guesswork around why bugs happen by showing exactly what users experienced. It captures console logs, errors, network requests, and pixel-perfect DOM recordings — compatible with all frameworks.
LogRocket's Galileo AI watches sessions for you, instantly identifying and explaining user struggles with automated monitoring of your entire product experience.
Modernize how you debug web and mobile apps — start monitoring for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowYou don’t need to guess what’s wrong with your Next.js app. I’ve mapped out the 8 biggest performance traps and the fixes that actually work.
Explore how to use Google’s new experimental Interest Invoker API for delays, popovers, and smarter hover UX.
Bolt.new revolutionizes how you build and deploy web apps with no-code development and seamless AI integration.
Learn how to get the most out of Cursor AI — one of the hottest tools in AI-assisted coding, with practical workflows and underrated features.