Editor’s note: This post was updated on 5 May 2023 to include additional examples of truncating text with CSS and JavaScript, as well as to include information about the accessibility implications of truncating text.
CSS is fantastic; we all know that. It has many unique features that enable us to achieve incredible responsiveness on the web. Have you ever wondered how the ellipses (...)
you see on some popular websites (as shown in the image below) are created?
Well, in this article, we will explore how to achieve multi-line truncations in CSS using the language of web JavaScript. Let’s go!
Well, in this article, we will explore different ways to truncate text with CSS. We’ll consider the differences between trimming and truncating text, and we’ll investigate the WCAG implications of truncating text.
Sit and enjoy the ride — Let’s go!
Jump ahead:
text-overflow
to truncate text
It’s easy to confuse the words “truncate” and “trim”, but actually they are quite distinct. In CSS, we cannot really compare truncate and trim and they are completely different properties.
As of this writing, the CSS standard doesn’t include the text-trim
property. Will this change in the future? Possibly, but it may not be necessary to add this functionality to CSS given that JavaScript already has the String.Prototype.trim()
method.
We can use the JavaScript String.Prototype.trim()
method to remove whitespace from the beginning and end of a string without modifying the original string or the CSS context of the text. Here’s an example:
let myBio = ' My name is Chinedu, and I work as a Software Engineer. How about you? ' let trimedText = myBio.trim() console.log(trimedText)
Truncation often involves cutting off text after a certain line depending on our needs as we build out our application. In most cases, truncating text in CSS refers to adding ellipses at the end of a sentence to indicate that there is more text to be read.
Truncating is quite the opposite of trim in many ways, one being that we have the text-overflow
CSS property available to help us truncate text. We can also truncate text with JavaScript.
text-overflow
to truncate textCSS offers several ways to truncate text. In this article, we’ll take a close look at the text-overflow
and -webkit-line-clamp
properties.
According to the MDN Docs , “The text-overflow CSS property sets how hidden overflow content is signaled to users. It can be clipped, displayed as an ellipses, or displayed as a custom string.” In simple terms, the CSS text-overflow
property is used to specify that text has overflowed its container and is hidden from users.
In this article, I will be looking at the two major text-overflow CSS properties.
clip
ellipses
N.B., there are other CSS text-overflow
properties like string
, initial
, and inherit
. I am not covering them here because, at the time of writing, they only have support on Firefox and Firefox for Android browsers. You can read more about them here
clip
for single-line text truncationclip
is the default value for the CSS text-overflow
property. It truncates text in a container at the end of the content area. When clip
is applied, the text isn’t accessible:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Text-overflow</title> <style> h3 { border: 1px solid #2a70a5; text-align: center; padding: 5px; color: #2a70a5; } .text-overflow-clip { border: 2px solid #2a70a5; padding: 20px 0; white-space: nowrap; width: 100%; overflow: hidden; text-overflow: clip; font-size: 50px; } </style> </head> <body> <h3>Clip</h3> <main class="text-overflow-clip">Lorem Ipsum bụ naanị ederede nke ụlọ ọrụ mbipụta na ụdị mbipụta. Lorem Ipsum abụrụla akwụkwọ ederede ọkọlọtọ ụlọ ọrụ kemgbe afọ 1500, mgbe onye nbipute amaghi ama were ụdị ụgbọ mmiri wee chịkọta ya iji mepụta akwụkwọ nlegharị anya. Ọ dịlarị ọ bụghị naanị narị afọ ise, kamakwa ọbịbịa n'ime ụdị elektrọnik, na-agbanwe agbanwebeghị. Emere ya na 1960 site na mwepụta nke akwụkwọ Letraset nwere akụkụ Lorem Ipsum, yana n'oge na-adịbeghị anya site na ngwa mbipụta desktọpụ dị ka Aldus PageMaker gụnyere ụdị Lorem Ipsum.</main> </body> </html>
ellipses
for single-line text truncationellipses
is another value for the CSS text-overflow
property; it clips the text and represents it using three horizontal dots:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Text-overflow</title> <style> h3 { border: 1px solid #2a70a5; text-align: center; padding: 5px; color: #2a70a5; } .text-overflow-ellipses { border: 2px solid #2a70a5; padding: 20px 0; white-space: nowrap; width: 100%; overflow: hidden; text-overflow: ellipsis; font-size: 50px; } </style> </head> <body> <h3>Ellipsis</h3> <main class="text-overflow-ellipses">Lorem Ipsum bụ naanị ederede nke ụlọ ọrụ mbipụta na ụdị mbipụta. Lorem Ipsum abụrụla akwụkwọ ederede ọkọlọtọ ụlọ ọrụ kemgbe afọ 1500, mgbe onye nbipute amaghi ama were ụdị ụgbọ mmiri wee chịkọta ya iji mepụta akwụkwọ nlegharị anya. Ọ dịlarị ọ bụghị naanị narị afọ ise, kamakwa ọbịbịa n'ime ụdị elektrọnik, na-agbanwe agbanwebeghị. Emere ya na 1960 site na mwepụta nke akwụkwọ Letraset nwere akụkụ Lorem Ipsum, yana n'oge na-adịbeghị anya site na ngwa mbipụta desktọpụ dị ka Aldus PageMaker gụnyere ụdị Lorem Ipsum.</main> </body> </html>
It’s important to note that while the text-overflow
property can be used to truncate text, it cannot do so on its own. Instead, two additional CSS properties are required:
white-Space: nowrap;
: forces text into a straight line and does not wrap to the next lineoverflow: hidden;
: causes text to be contained within the parent containerIn some situations, I have found myself wanting to add an element such as an icon after the ellipses. But, when the line becomes too long, the element is truncated with the ellipses. The challenge here is getting the element to stay after the ellipses.
So, how do we add the element after the ellipses? Let’s say we have the below HTML:
<div class="parent-box box"> <div class="child-box"> You are learning text truncation with javascript which is done with these three steps </div> </div> <div class="parent-box box"> <div class="child-box no-max-width"> You are learning text truncation with javascript which is done with these three steps </div> </div>
In order to achieve this, we set the ::after
pseudo-element to the parent element .box
. Then, we set the next div
with class .child-box
and give it a display of inline-block
. This allows the pseudo-element of the .parent-box
to come after the width of the .child-box
.
If the defined max-width
is exceeded, then the overflow
set to hidden
comes into play. This enables us to have the ellipsis
and the element of the .parent-box
if there is a text-overflow
.
N.B., the trick here is to not declare the pseudo-element to an element that we declared overflow
width on. This should be done to the parent element, which will, at some point, trim out the content once the max-width
is reached:
.parent-box .child-box { text-overflow: ellipsis; display: inline-block; max-width: 70%; width: auto; white-space: nowrap; overflow: hidden; } .parent-box .child-box.no-max-width { max-width: none; } .parent-box .child-box::before { display: none; } .parent-box .box::after { content: 'X'; display: inline-block; }
To learn more about pseudo-elements, check out this guide to CSS pseudo-elements.
Next, let’s look at truncating text with the CSS -webkit-line-clamp
property
-webkit-line-clamp
for multi-line text truncationThe CSS -webkit-line-clamp
property is very useful when we want to truncate multiple lines of text.
According to the MDN Docs, “The CSS -webkit-line-clamp
property allows us to limit the content of a block to a specified number of lines.”
Also, for this to work the display
must be set to -webkit-box
, the -webkit-box-orient
must be set to vertical
, and the overflow
must be set to hidden
:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Line Clamp</title> <style> .container { width: 360px; margin: 0 auto; padding: 10px; border-radius: 4px; text-align: center; background-color: black; color: white; } .container > h3 { color: #2a70a5; } .text-overflow-clamp { width: 100%; /* this code clamps based on specified lines */ overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 5; display: -webkit-box; } </style> </head> <body> <div class="container"> <h3>-webkit-line-clamp</h3> <div class="text-overflow-clamp">Lorem Ipsum bụ naanị ederede nke ụlọ ọrụ mbipụta na ụdị mbipụta. Lorem Ipsum abụrụla akwụkwọ ederede ọkọlọtọ ụlọ ọrụ kemgbe afọ 1500, mgbe onye nbipute amaghi ama were ụdị ụgbọ mmiri wee chịkọta ya iji mepụta akwụkwọ nlegharị anya. Ọ dịlarị ọ bụghị naanị narị afọ ise, kamakwa ọbịbịa n'ime ụdị elektrọnik, na-agbanwe agbanwebeghị. Emere ya na 1960 site na mwepụta nke akwụkwọ Letraset nwere akụkụ Lorem Ipsum, yana n'oge na-adịbeghị anya site na ngwa mbipụta desktọpụ dị ka Aldus PageMaker gụnyere ụdị Lorem Ipsum.</div> </div> </body> </html>
-webkit-line-clamp
also has the full support of all the major browsers, so feel free to use it in your projects. You can read more about the browser support at the MDN Docs.
text-overflow
with FlexboxI have noticed that truncated text on a flex item’s child messes up the flex item. For instance, in a situation where we have a div
with an inner nested element like a p
tag, ellipses don’t work on the child element of the flex parent.
Take a look at the code below:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Line Clamp</title> <style> .container { display: flex; flex-wrap: wrap; } .container h1 { align-self: center; } .container .possible-issues { flex: 1; border: 1px solid black; } .container .possible-issues p { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border: 1px solid red } </style> </head> <body> <div class="container"> <h3>Possible issues with flex and overflow</h3> <div class="possible-issues"> <p>Lorem Ipsum bụ naanị ederede nke ụlọ ọrụ mbipụta na ụdị mbipụta. Lorem Ipsum abụrụla akwụkwọ ederede ọkọlọtọ ụlọ ọrụ kemgbe afọ 1500, mgbe onye nbipute amaghi ama were ụdị ụgbọ mmiri wee chịkọta ya iji mepụta akwụkwọ nlegharị anya. Ọ dịlarị ọ bụghị naanị narị afọ ise, kamakwa ọbịbịa n'ime ụdị elektrọnik, na-agbanwe agbanwebeghị. Emere ya na 1960 site na mwepụta nke akwụkwọ Letraset nwere akụkụ Lorem Ipsum, yana n'oge na-adịbeghị anya site na ngwa mbipụta desktọpụ dị ka Aldus PageMaker gụnyere ụdị Lorem Ipsum. </p> </div> </div> </body> </html>
The possible issues that can occur with Flexbox and test-overview can be visualized in the above code and in the below image:
Here’s a description of the labeled areas:
p
tag; this is the flex item’s childdiv
container; the flex itemwhite-space: nowrap;
, overflow: hidden;
, and text-overflow: ellipsis;
the ellipses don’t work the text overflow
parents containerIn order to fix this, we have to understand what’s actually the issue here. The possible-issues
flex item container has a min-width
set to auto
by default. To fix this we have to set min-width
to 0
; this will allow smaller content to shrink and then the ellipses will be applied:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Line Clamp</title> <style> .container { display: flex; flex-direction: column; /* flex-wrap: wrap; */ } .container h1 { align-self: center; } .container .possible-issues { flex: 1; min-width: 0; border: 1px solid black; } .container .possible-issues p { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border: 1px solid red } </style> </head> <body> <div class="container"> <h3>Possible issues with flex and overflow</h3> <div class="possible-issues"> <p>Lorem Ipsum bụ naanị ederede nke ụlọ ọrụ mbipụta na ụdị mbipụta. Lorem Ipsum abụrụla akwụkwọ ederede ọkọlọtọ ụlọ ọrụ kemgbe afọ 1500, mgbe onye nbipute amaghi ama were ụdị ụgbọ mmiri wee chịkọta ya iji mepụta akwụkwọ nlegharị anya. Ọ dịlarị ọ bụghị naanị narị afọ ise, kamakwa ọbịbịa n'ime ụdị elektrọnik, na-agbanwe agbanwebeghị. Emere ya na 1960 site na mwepụta nke akwụkwọ Letraset nwere akụkụ Lorem Ipsum, yana n'oge na-adịbeghị anya site na ngwa mbipụta desktọpụ dị ka Aldus PageMaker gụnyere ụdị Lorem Ipsum. </p> </div> </div> </body> </html>
N.B., the flex-wrap
property was removed because it had some weird unexpected behavior
Here’s an image depicting text with ellipses. This image was created with the above code, setting flex item’s min-width
to 0
to stop the overflow and enable the ellipses:
Now, let’s look at how we can achieve this using JavaScript. First, let’s create a function called truncate
and pass in the words to be truncated as parameters. We will also give a max-length Parameter
:
Const truncate (words, maxlength)=>{}
Then, we’ll use the slice
method to truncate our text, and we will also return our truncated text from within our truncate
function.
N.B., we will give the slice
method an initial value of zero (0)
because we will have to truncate from the beginning of words to the specified area where we wish to stop:
Const truncate (words, maxlength)=>{ return `${words.slice(0, maxlength)} …` }
Now, for the last and final step, let’s wrap it up by passing the words
and the maxlength
as arguments:
Const words = "You are learning text truncation with javascript which is done with these three steps" Const truncate (words, maxlength)=>{ return `${words.slice(0, maxlength)} …` } truncate(words, 20)
In this case, the maxLength
handles a particular edge case for a situation where the string we want to truncate isn’t long enough to be truncated.
Here, we want to return the original string without truncating it. However, in a situation where this condition is satisfied, we want to truncate and add the ellipses at the end of the string.
Text truncation can negatively affect readability for users with visual disabilities as it is nearly impossible for such users to access text that has been hidden from the user interface.
According to WCAG, in order to be accessible to everyone, web content should be:
Here are some ways we can try to solve perceivability issues caused by text truncation:
Here’s an example of how we can intuitively handle user-generated content in a way that abides by WCAG guidelines and principles:
Imagine that this is dynamic content coming from a database and we only want to show five lines of text by default unless the button is clicked. Here, I use the “Read more” button to toggle between the visible and hidden content. The first image shows a truncated text description ending with ellipses and a ”Read more” button.
In the second image, the “Read more” button has already been clicked so more content is visible and the button now says “Read less.” By handling the content in this way, we can abide by the WCAG guidelines and principles.
See the Pen
Hide and show description for hidden text by Chinedu Victor (@chineduvictor7)
on CodePen.
In this article, we reviewed how to truncate text in CSS using several CSS and JavaScript techniques. We also looked at how to add an element after the ellipses, which is quite tricky to achieve in many cases. We covered the nuances of truncation and WCAG principles and guidelines, explored issues that might arise from working with Flexbox and text-overflow
, and discussed the difference between trim and truncate.
I hope you learned a lot from this article, and feel free to suggest other suggestions that would keep improving this article that I may have missed. Thank you for taking the time to read this one, and keep coding!
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 is like a DVR for web and mobile apps, recording everything that happens in your web app, mobile app, or website. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.
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 nowJavaScript’s Date API has many limitations. Explore alternative libraries like Moment.js, date-fns, and the new Temporal API.
Explore use cases for using npm vs. npx such as long-term dependency management or temporary tasks and running packages on the fly.
Validating and auditing AI-generated code reduces code errors and ensures that code is compliant.
Build a real-time image background remover in Vue using Transformers.js and WebGPU for client-side processing with privacy and efficiency.