Javascript Tutorial - How to Auto Ellipse Text

Skill

Javascript Tutorial - How to Auto Ellipse Text

Posted in:
Example Ellipsis on a tab

Example ellipsis on a tab

This tutorial will demonstrate how to add ellipsis (...) to text when it exceeds a desired length using Javascript.

Microsoft was nice enough to invent the CSS tag, textOverflow:ellipsis, for Internet Explorer, but unfortunately this doesn't exist on other browsers. What I'm going to do is create a Javascript function that will automatically add ellipsis to a string when its length exceeds a certain width in pixels. This function should work on most current browsers.

Let's start by defining the signature for this function.

function autoEllipseText(element, text, width)

This function takes three arguments: the element the text will be added to, the text to truncate, and the desired width in pixels. The reason there needs to be an element is because Javascript has no way to tell us the text's width in pixels. We have to modify the DOM and have the browser tell us what the width is. Using the browser also takes care of any font size changes your users may have made to their browser. This function will return a truncated string with a set of ellipsis. If the string's width is already less than width, the function will return the original text.

The first thing we're going to do is add a span to the element passed in. We're going to use the span to tell us how wide the text is.

function autoEllipseText(element, text, width)
{
   element.innerHTML = '<span id="ellipsisSpan";
      style="white-space:nowrap;">'
+ text + '</span>';
}

We added a span with the id "ellipsisSpan" to the element passed in to the function. You'll want to make sure there isn't anything in the element before it's passed to this function, because this call will remove it. We added a white-space:nowrap style to the span to make sure the text doesn't wrap to a new line.

Now we can start removing characters from the text to make it fits in the desired width.

function autoEllipseText(element, text, width)
{
   element.innerHTML = '<span id="ellipsisSpan"
      style="white-space:nowrap;">'
+ text + '</span>';
   inSpan = document.getElementById('ellipsisSpan');
   if(inSpan.offsetWidth > width)
   {
      var i = 1;
      inSpan.innerHTML = '';
      while(inSpan.offsetWidth < (width) && i < text.length)
      {
         inSpan.innerHTML = text.substr(0,i) + '...';
         i++;
      }
               
      returnText = inSpan.innerHTML;
      element.innerHTML = '';
      return returnText;
   }
   return text;
}

The first thing this section of code does it to get the span element we just created by calling document.getElementById(). It then compares the span's offsetWidth to the desired width to see if the text needs to be truncated. The while loop builds the text up character by character until it exceeds the desired width. Once this happens, the function removes the added span element and returns the new text. For the sake of simplicity, I've done a simple loop adding characters one at a time. This isn't very efficient for long input strings. For a more efficient implementation, replace that loop with a O(log(n)) algorithm such as a binary search. That will greatly reduce the number of comparisons needed to build the output string.

If you wanted, you could remove the line that resets the element's innerHTML and the new text would already be added to passed in element. I clear the element because someone might want to do something else with the text.

Below is an example using the code above. This is a table with one cell which is 90 pixels wide. When the button is pressed, the cell's text will be set to whatever was typed in the text box. Whenever something is typed that is longer than 80 pixels, the function will add ellipsis to guarantee that it fits. I made it 80 pixels to make room for the borders and any default padding. This example only works for text with no html markup. For a more robust implementation, you may want to escape any special characters that are passed into the autoEllipseText() function.

Text

Here's all the finished code to produce the above controls.

function setCellText()
{
   cellElement = document.getElementById('textCell');
   textBoxElement = document.getElementById('cellText');
   cellElement.innerHTML =
       autoEllipseText(cellElement, textBoxElement.value, 80);
}

<table border="1">
   <tr>
      <td id="textCell" width="90px">Text</td>
   </tr>
</table>

<input type="text" id="cellText"></input>
<input type="button" onclick="setCellText();" value="Update Text" ></input>

I added a helper function, setCellText(), which is called when the button is clicked. This function sets the cell's innerHTML to the output of a call to autoEllipseText().

That's all that's required to automatically add ellipsis to text using Javascript. If you'd like to see this code in action, our site Gaming Textures uses auto ellipsis to limit the amount of text displayed on the search tabs.

Ozgür
07/23/2007 - 08:01

so if i am not mistaken,

we are losing that "longer than expected" part of the text.

is there any way that the user can reach the full text, in case it is needed?

reply

The Reddest
07/23/2007 - 09:10

A common solution is to provide the full text in a tooltip. To put text in a tooltip use the following syntax:

<span title="Full Text Here">Truncated Text Here</span>

The title attribute of the span element is what holds the tooltip's text. So in the function autoEllipseText(), change the line return returnText; to:

return '<span title="' + text + '">' + returnText + '</span>';

Now when a user mouses over the truncated text, the full text will appear in a tooltip. Thanks for the question!

reply

Joe
08/21/2007 - 20:26

This is assuming your website targets en-us only. In other languages/cultures, if you start trimming off random chars then you might change the meaning of the word and the way it gets rendered. This is why the platform normally provides API to do the ellipsis work...

reply

Brad Isbell
01/09/2008 - 10:44

This code is great!! I've been looking for something like this off and on for months!

reply

Jeremy
02/03/2008 - 01:48

very interesting but if it's not too much trouble then I want some help with this case I have which is that I have a textbox that I set it's width to 200px and in firefox it scrolls left when the lines exceeds it's limit so my question is how can I stop the textbox from scrolling left and force the text to wrap?

Best Regards.

reply

Godheval
02/07/2008 - 17:01

How can I call the function "setCellText" without using a button?

http://www.godheval.net/5.0/

And if I'm using IDs, does that mean I can only do it once, and not on all of my module content - see right side of page.

reply

Ted
12/08/2008 - 17:04

funny stuff. i’ve been looking at a few other proposed methods and your function seems to deal with all the major concerns quite well… but now you get new questions like “what about other languages?”

nice job.

reply

ynm
11/20/2009 - 17:29

this is pretty awesome. The only issue is i would like the limited text to run across 2 lines. This is awesome for 1 line of text. wish i could wrap it then truncate :\

reply

puexine
11/21/2010 - 05:04

if there is no ID or Class in HTML file,or we can't modify it,but there is have a "li" element.how can i edit the code?

reply

puexine
11/21/2010 - 06:10

I am not a programmer, so there is a problem need your help. Here, how this can be achieved it? thanks in advance!!

<ul class="menu">
    <li><a href="#1">This is a long piece of text which will need to be truncated.</li>
    <li><a href="#2">This is a long piece of text which will need to be truncated.</li>
    <li><a href="#3">This is a long piece of text which will need to be truncated.</li>
    <li><a href="#4">This is a long piece of text which will need to be truncated.</li>
    <li><a href="#5">This is a long piece of text which will need to be truncated.</li>
</ul>

reply

micha
11/22/2010 - 18:37

great! thanks a lot for that

reply

John Lander
12/03/2010 - 07:18

Awesome!

reply

Ross Morsali
02/04/2011 - 10:48

Hi, thanks for this it is perfect!

I've customised this so that it is a now a jQuery plugin - let me know if that will be of any use to anyone!?! :D

reply

The Reddest
02/04/2011 - 11:26

Neat! I don't want to belittle your efforts, but was there something that the actual jQuery tabs didn't offer that made you convert this into a plugin?

Edit: whoops, I thought this was our tabs tutorial. Never mind. Great effort!

reply

Ross Morsali
02/12/2011 - 01:10

Haha no worries! Yeah, yours was the best auto ellipse script I found and just need converting for jQuery so I could easily add it to all H3 tags for example (as well as the fact I was already using the jQuery library all over the place).

$("h3").autoEllipse(vars);

Like I said, if you want the code just let me know where to send it to :)

Cheers
Ross

reply

The Reddest
02/13/2011 - 19:49

If you don't mind, I'd really like to publish your source in a new post. Zip it up and email it to support@switchonthecode.com. If you've got a website or something, put that in there so we can attribute you correctly!

reply

Ross Morsali
02/15/2011 - 04:37

Cool will do in the next couple of days! I'll just tidy it up and comment correct :)

reply

Ross Morsali
05/06/2011 - 09:32

Hey, Just to let you know I sent you an email a couple of weeks ago about this and had no response :S

reply

Ross Morsali
08/23/2011 - 07:36

Hey, just dropped you a mail.. after a long wait I finally got it up on github, I plan on improving this over the coming weeks further :)

https://github.com/rmorse/AutoEllipse

reply

Ross Morsali
08/26/2011 - 07:41

Updated project name as ellipse isn't really the right word! (its ellipsis.. doh!) https://github.com/rmorse/AutoEllipsis

reply

ferdz
03/15/2011 - 20:28

hi The Reddest,

Your implementation works for a separate textbox or input field. It is not applicable when applied on the same textbox.The same textbox returns "htmlfile: Unknown runtime error" when you try to assign an html that includes the span.

So Ross' update using jQuery should probably work.

reply

Ross Morsali
08/23/2011 - 07:36

See above :)

reply

Brajesh Kumar singh
05/18/2011 - 13:38

Great works like a charm......

reply

Sébastien Piquemal
01/30/2012 - 10:17

Great !!! There's something wrong in the code though.

    while(inSpan.offsetWidth < (width) && i < text.length)
      {
         inSpan.innerHTML = text.substr(0,i) + '...';
         i++;
      }

When you exit the "while" with "inSpan.offsetWidth > width", you're already one character too far.

reply

Add Comment

Put code snippets inside language tags:
[language] [/language]

Examples:
[javascript] [/javascript]
[actionscript] [/actionscript]
[csharp] [/csharp]

See here for supported languages.

Javascript must be enabled to submit anonymous comments - or you can login.
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.