- How to handle long text overflow with pure CSS (truncate/ellipsis, wrap)
- 1. Wrapping text
- 1.2 The word-break property
- 1.2 The overflow-wrap property
- 2. Truncating text
- 2.1 The text-overflow property
- Single line
- Multiline
- 2.2 The line-clamp property
- CSS Ellipsis for Single-Line and Multi-Line Text
- Single-line ellipsis
- Multi-line ellipsis
- Conclusion
- How can I do text-overflow: ellipsis on two lines?
- 5 Answers 5
- Pure CSS for multiline truncation with ellipsis
- What are the options?
- 1. -Webkit-line-clamp property
- 2. Text-overflow: -o-ellipsis-lastline
- 3. Using JavaScript
- 4. Truncate the text on the server
- A Simple, Pure CSS Solution
- How It Works
- 1. The text is more than 3 lines
- 2. The text is less than 3 lines
- 3. The text is exactly 3 lines
- Benefits
- A couple things to watch out for
How to handle long text overflow with pure CSS (truncate/ellipsis, wrap)
When working on a website or a web app texts are often overlooked, that’s when issues like overflowing text occur. To solve that, you can use some solutions like truncating or ellipsizing a text (add three dots) or wrapping the text.
Overflowing text content quite often happens in the following cases:
- For long words;
- For long URL’s;
- On mobile devices;
- For narrow container elements;
- For table cells;
- For button elements.
Depending on the CSS styles you have, the text overflow will usually look either like a horizontal scroll or like a cut-off content.
Consider the following issue. There’s a fixed-width container on a page with a link containing and pointing to a long URL. The link text will overflow the container and will look messy, as well as it can produce an unwanted horizontal scroll on smaller screen sizes.
1. Wrapping text
1.2 The word-break property
One way to handle long text in CSS is to wrap it to the next line. This approach is handy when you don’t have to worry about text spanning multiline. When using word-break property you have two options how to wrap it:
- break-all — this will break text once the characters don’t fit inside the container
- break-word — this will break text once the characters don’t fit inside the container but it will preserve the word sequence. NOTE: this is a deprecated API and it is not recommended to use.
.container a word-break: break-all; >
Browser support for word-break property: https://caniuse.com/word-break
1.2 The overflow-wrap property
Another option to wrap text is to use the overflow-wrap property. This property also has two options for wrapping:
- anywhere — will break text at any given point if it doesn’t fit;
- break-word — same as anywhere except it will break long words at arbitrary points.
.container a overflow-wrap: break-word; >
Browser support for overflow-wrap property: https://caniuse.com/wordwrap
2. Truncating text
2.1 The text-overflow property
The text-overflow property will add an ellipsis (will add three dots) to a text if it doesn’t fit inside the container. This approach is handy if you want to keep text in a single line. However, with some additional modifications, it can be made for multiline text as well.
The text-overflow property with a value of ellipsis must be set on a parent element, relative to the text. Two additional properties must be specified overflow and white-space .
NOTE: Learn how to handle text overflow for select tag.
Single line
.container overflow: hidden; white-space: nowrap; text-overflow: ellipsis; >
Multiline
For the multiline solution the white-space property must be removed, this way the text will be truncated on the last available line.
.container overflow: hidden; text-overflow: ellipsis; >
Browser support for text-overflow property: https://caniuse.com/text-overflow
2.2 The line-clamp property
A more modern approach is the line-clamp property which will limit the container text to a specified number of lines. As well as add the three dots at the end. This property will only work with a -webkit- vendor prefix and a display property set to -webkit-box or -webkit-inline-box .
Unline the text-overflow solution, this approach is straightforward and more understandable, when it comes to truncating multiline text. The line-clamp property must be set to the element that is overflowing and the value should be equal to the number of lines to span.
.container a overflow: hidden; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; >
Browser support for the line-clamp property: https://caniuse.com/css-line-clamp
A full demo is available on CodePen:
CSS Ellipsis for Single-Line and Multi-Line Text
Learn to truncate text and add ellipsis at the end using CSS. For both, single-line and multi-line text.
So your designer has asked you to add the three dots at the end when the text doesn’t fit, and you have no clue how to do that?
Don’t worry, it’s super simple to do with CSS.
By the way, those three dots at the end are called ellipsis.
Real quick — would you like to master CSS and learn Web Development? If so, be sure to check out the platform I recommend to learn coding online:
Single-line ellipsis
Use text-overflow: ellipsis; to automatically truncate the text when it overflows the container and add the three dots at the end.
The element needs to get resized and the text has to stay in one line for the ellipsis to show up, so here are all 3 CSS lines you need:
Multi-line ellipsis
You will soon find, that text-overflow: ellipsis; doesn’t work when the text wraps to an extra line.
To truncate multi-line text and add an ellipsis at the end of the last line use the experimental -webkit-box box model (don’t worry it’s supported in all major browsers):
Conclusion
It’s trivial to truncate the overflowing text and add an ellipsis at the end of a single line. Adding an ellipsis for multiline text is a bit more tricky, so this post should help you.
You can find the code examples for this article on my GitHub: https://github.com/vincaslt/twitter-code/tree/main/src/ellipsis
Since you’re learning CSS tricks, why not go through my practical CSS guide? It will take only 5 minutes, but it will teach you all of the CSS you need in practice:
How can I do text-overflow: ellipsis on two lines?
I have a container where the text may expand to two lines and it’s 40px in height, with an 18px font size. When I do:
text-overflow: ellipsis; white-space: nowrap;
Then it correctly shows the 2 lines but there’s no «. » at the end. How do I achieve this so it correctly uses both lines AND finishes with «. » on the second line?
display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; is the best way to do this.
5 Answers 5
You can do it using -webkit-line-clamp . But a hack is needed. You need to set the height of the div such that it can accommodate only two lines.
Pellentesque habitant morbi tristique senectus et netus et
Add a span to the container, which will hold the text:
.container < overflow: hidden; position: relative; background: white; //or other color >.container:after < content: '. '; //the ellipsis position: absolute; //positioned in bottom-right bottom: 0; //. right: 0; //. padding: 0 0.3em; //give some separation from text background: inherit; //same color as container >.container span:after < content: '\0000a0'; //a space position: absolute; //to cover up ellipsis if needed width: 1000px; //. z-index: 1; //. background: white; //must match container's color. can't use inherit here. >
Resize the container, and you’ll see that the ellipsis displays only as necessary.
Should work in all modern browsers.
@Tom, thanks. I think you need to specify a background color. Otherwise, the ellipsis may show unnecessarily. See the first div at jsfiddle.net/j7863uw5/44.
Just want to add my two cents. The closest pure CSS solution that works is the -webkit-line-clamp method but is limited to webkit browsers and is the remnant of an old flexbox implementation (which may be removed in the future).
Perhaps you should reconsider if you really require an ellipses on vertically overflowed text.
I suggest instead use a scroll-able text box instead. I believe this is the best solution because of these three reasons:
- Works in every major browser
- No css workarounds, hacks, or javascript involved
- Communicates well to the user that text is cutoff but gives them the option to scroll through it if they wish — plus, users are already accustomed to vertical scroll bars
Here is sample code for a text box:
If I had to choose though, I would use a javascript solution along the lines of Succint which deletes words after a certain amount and appends an . at the end. This is great if you use React because you can implement all the code required inside the component as a function and if you need the original text you still have it as a props value.
Pure CSS for multiline truncation with ellipsis
BLOG UPDATE (updated on Nov 2018):
Hacking UI was founded by us – David Tintner and Sagi Shrieber – but since then we each have gone down our own paths, and would love to invite you there.
David is now working full time on Thoughtleaders – a marketplace for higly targeted content-marketing solutions for bloggers and brands.
Sagi has launched a podcast and community of online entrepreneurs called Mindful & Ruthless. There he teaches and gives free tips and strategies on how to build an online brand, and make it into a business while hosting a weekly podcast interviewing some of the world’s most inspiring online entrepreneurs. You can subscribe to the podcast on iTunes, Youtube, Spotify, or your favorite podcast app.
As of today, this is what we – David and Sagi – are doing FULL TIME.
CSS3 gave us the wonderful property, text-overflow , which can do things like create ellipsis and gracefully cut off words. However, text-overflow has a serious limitation: it only works on a single line of text.
A few days ago I had to truncate a multiline block of text. It’s a common problem, but I was a disappointed because we still don’t have a simple, cross-browser CSS solution for it. I tried a few ideas, but each time I found that the ‘…’ wasn’t quite right. Sometimes it appeared far from the end of the text or fell over to the next line.
Finally I found the ideal solution.
What are the options?
In order to fully understand why this pure CSS solution is so awesome, I want to run through a few of the alternatives and the problems with each.
If you’d like, you can jump ahead to check out a live example of the solution: codepen demo.
1. -Webkit-line-clamp property
I really like this for it’s simplicity, but unfortunately it is not cross browser (doesn’t work in Firefox and Internet Explorer). I hope that in future we will have a regular, non-vendor-prefixed CSS property.
To use -webkit-line-clamp, add the following to your CSS:
2. Text-overflow: -o-ellipsis-lastline
As of version 10.60, Opera added the ability to clip text on multi-line blocks. To be honest I have never tried this property, but it allows you to use -webkit-line-clamp .
3. Using JavaScript
Here’s a simple Javascript function for truncating text, but it has some serious drawbacks.
function ellipsizeTextBox(id) < var el = document.getElementById(id); var wordArray = el.innerHTML.split(' '); while(el.scrollHeight >el.offsetHeight) < wordArray.pop(); el.innerHTML = wordArray.join(' ') + '. '; >> ellipsizeTextBox(‘block-with-text);
Some of the drawbacks of this method include requiring the block of text to have a fixed height, not waiting for the font to load and the possibility that the ‘…’ will appear on the next line after the main text.
4. Truncate the text on the server
This is an example of truncating the text in PHP. This method works fine in limiting the text, but requires messing with the server-side just to deal with presentation, which is supposed to the be the job of CSS.
$text = 'your long long text'; $maxPos = 100; if (strlen($text) > $maxPos)
A Simple, Pure CSS Solution
Clearly none of these options are perfect. I wanted an easier and more bulletproof way to handle this, so I found that we can truncate text using two carefully placed CSS pseudo elements.
Here’s the full CSS. We’ll walk through the code below.
/* styles for '. ' */ .block-with-text < /* hide text if it more than N lines */ overflow: hidden; /* for set '. ' in absolute position */ position: relative; /* use this value to count block height */ line-height: 1.2em; /* max-height = line-height (1.2) * lines max number (3) */ max-height: 3.6em; /* fix problem when last visible word doesn't adjoin right side */ text-align: justify; /* place for '. ' */ margin-right: -1em; padding-right: 1em; >/* create the . */ .block-with-text:before < /* points in the end */ content: '. '; /* absolute position */ position: absolute; /* set position to right bottom corner of block */ right: 0; bottom: 0; >/* hide . if we have text, which is less than or equal to max lines */ .block-with-text:after < /* points in the end */ content: ''; /* absolute position */ position: absolute; /* set position to right bottom corner of text */ right: 0; /* set width and height */ width: 1em; height: 1em; margin-top: 0.2em; /* bg color = bg color under block */ background: white; >
How It Works
Let’s imagine that we need to contain a block of text to a max of 3 lines. In order to do so, we have to handle the following cases:
1. The text is more than 3 lines
2. The text is less than 3 lines
3. The text is exactly 3 lines
Benefits
- 1. Pure CSS
- 2. Responsive
- 3. No need to recalculate on resize or font’s load event
- 4. Cross browser
A couple things to watch out for
Unfortunately this solution also has some drawbacks:
- 1. We need to have a plain background color for covering up the ‘…’ if the text is less than the max number of lines.
- 2. we need some space for ‘…’, and if the parent block has overflow: hidden or overflow: auto then we need to remove style margin-right: -1em; .
Also for the patient reader, I created an SCSS mixin to do this faster:
codepen demo
/* mixin for multiline */ @mixin multiLineEllipsis($lineHeight: 1.2em, $lineCount: 1, $bgColor: white) < overflow: hidden; position: relative; line-height: $lineHeight; max-height: $lineHeight * $lineCount; text-align: justify; margin-right: -1em; padding-right: 1em; &:before < content: '. '; position: absolute; right: 0; bottom: 0; >&:after < content: ''; position: absolute; right: 0; width: 1em; height: 1em; margin-top: 0.2em; background: $bgColor; >> .block-with-text
What do you think? Do you have another solution for multiline text truncation? Let me know in the comments.