ThreeDots

jquery-logo-256

Episode 10

Sometimes the text …

… is too long …
… won’t fit within the number of rows you have available.

Sometimes all you need is … ThreeDots! (a jQuery plugin)

For example —

This: When restricted to 2 lines by ThreeDots, can become:
There was once a brown fox
that liked to eat chocolate
pudding.
There was once a brown fox
that liked to eat …
There was once a brown fox
that liked to eat chocolate
pudding.
There was once a brown fox
that liked to (click for more)

… and most any other permutation you desire.

To Ellipsize

There are many scenarios in the display of online text where shortened, truncated representations are best used.  For these scenarios, many products opt for the implementation of ellipses.

el·lip·sis   (ĭ-lĭpsĭs)

n., pl., -ses (-sēz).

  1. The omission of a word or phrase necessary for a complete syntactical construction but not necessary for understanding.
  2. An example of such omission.
    • A mark or series of marks ( . . . or * * * , for example) used in writing or printing to indicate an omission, especially of letters or words.

[Latin ellīpsis, from Greek elleipsis, from elleipein, to fall short. See ellipse.]
from <http://www.answers.com/topic/ellipsis>

Many online products employ ellipses within their products to improve various aspects of the User Experience, such as:

allowing for easy summary scanning of page content, and
fitting more diversity of content into a smaller space.

Most often people truncate the text by character count, on both the client- and server-sides, which does not take into account the variable dimensions of the text being truncated.  There are also a few CSS hacks out there, albeit with future standardized support currently being called into question, and custom, per-browser efforts required for successful implementation.

I too, on so many projects, have encountered the challenge of wanting to limit text to only a few lines or make sure that, no matter what, the text always fits within the space provided.  People, myself included, on similar product feature missions have been forced to make compromises of design and experience, without the existence of a simple script/tool to carry out the task, to accommodate the time constraints and complexity of coding the ideal solution.

So, finally, I sat down, put the time in, and created the ThreeDots jQuery plugin for…

… when text is too long…
… when text doesn’t fit within the available space …
… when you want to employ highly configurable and flexible ellipses within your web product…

… so that never again, would I, or anyone else have to compromise their vision where that vision bumps up against the need for the smart implementation of ellipses in your web product.

Usage

ThreeDots is a customizable jQuery plugin for the smart truncation of text.  It shortens identified text to fit specified dimensions (e.g. number of rows within a container of explicitly defined width) and appends the desired ellipsis style if/when truncation occurs.

Sample 1:

<div class='text_here'>
	<span class='ellipsis_text'>
		TEXT
	</span>
</div>
$('.text_here').ThreeDots();  // USE DEFAULTS
$('.text_here2').ThreeDots({ max_rows:3 });

Sample 2:

<div class='text_here'>
	<span class='ellipsis_text'>
		TEXT
	</span>
</div>
threedots_object = $('.text_here').ThreeDots();
threedots_object.update();

Sample 3:

<div class='text here'>
	<span class='something'>
		TEXT
	</span>
</div>
threedots_object2 = $('.text_here').ThreeDots( {text_span_class: 'something'} );
threedots_object2.update( {text_span_class: 'something'} );

As a Method

When initialized, the ThreeDots plugin creates and assigns the full set of identified text to each container element, class=’text_here’, as a publicly accessible attribute, ‘threedots’.  The method implementation supports chaining and returns the jQuery object.

<div class='text_here' threedots='original text'>
	<span class='ellipsis_text'>
		original text
	</span>
</div>

Note, to implement the text that you wish to ellipsize, it must be wrapped in a span assigned either the default class ‘ellipsis_text’ or other custom class of your preference — customizable via the options/settings.

If the text becomes truncated to fit within the constrained space as defined by the container element that holds the ‘ellipsis_text’ span, then an additional span is appended within the container object, and after the ‘ellipsis_text’ span. 

<div class='text_here' threedots='original text'>
	<span class='ellipsis_text'>
		original text
	</span>
	<span class='threedots_ellipsis'>
		...
	</span>
</div>

The span class of ‘threedots_ellipsis’ can also be customized via the options/settings and have it’s own CSS/jQuery styles/actions/etc. applied to it as desired.  Put another way, the ellipsis is NOT constrained to ‘…’, but can be any text or HTML you desire.

If any of the specified settings are invalid or the ‘ellipsis_text’ span is missing, ThreeDots will abort its processing and the initial text will be left untouched.

IMPORTANT:  The horizontal constraints placed upon each row are controlled by the container object.  The container object is the object specified in the primary selector.

$('container_object').ThreeDots();

When using ThreeDots, the following additional methods can be used…

ThreeDots.update()

Refreshes  the text within the target object inline with the options provided. Note that the current implementation of options/settings are destructive.  This means that whenever settings are specified, they are merged with the DEFAULT settings and applied to the current object(s), and destroy/override any previously specified options/settings.

var obj = $('.text_here').ThreeDots();	// uses DEFAULT: max_rows = 2
obj.update({max_rows:3});				// update the text with max_rows = 3

Settings

By default, the three dots ellipsis (““) is used, as shown in the prior examples, and limits text to a maximum of 2 lines.  These and many other characteristics are fully customizable, and fully itemized and explained below.

To change these settings, they can either be accessed directly…

$.fn.ThreeDots.settings.max_rows = 4;

… or at the time of initialization or update …

// configuring the initial settings to use
var obj3 = $('.text_here').ThreeDots({ max_rows: 4 });

// changing the applied settings via an update call to the same text region(s)
obj3.ThreeDots.update({ max_rows: 2 });

The default settings data structure is…

$.fn.ThreeDots.settings = {
	valid_delimiters:         [' ', ',', '.'],			// what defines the bounds of a word to you?
	ellipsis_string:         '...',
	max_rows:                        2,
	text_span_class:        'ellipsis_text',
	e_span_class:                'threedots_ellipsis',
	whole_word:                        true,
	allow_dangle:                false,
	alt_text_e:                 false,					// if true, mouse over of ellipsis displays the full text
	alt_text_t:                 false					// if true & if ellipsis displayed, mouse over of text displays the full text
};

The parameters are defined (and all can be overridden) thus…

valid_delimiters

  • a character array of special characters upon which the text string may be broken up
  • defines what characters can be used to express the bounds of a word
  • all elements in this array must be 1 character in length
  • any delimiter less than or greater than 1 character will be ignored
  • if valid_delimiters contains no valid content, then nothing will be processed

ellipsis_string

  • defines what to display at the tail end of the text provided if the text becomes truncated to fit within the space defined by the container object
  • ellipsis_string can be text or HTML (e.g. ‘<a href=’url’>click for more</a>’)

max_rows

  • specifies the upper limit for the number of rows that the object’s text can use
  • if the displayed text is determined to use less than max_rows, then no operations will be performed upon the provided text and no ellipsis displayed
  • max_rows must be greater than 0 (ZERO)

text_span_class

  • by default ThreeDots will look within the specified object(s) for a span of the class ‘ellipsis_text’
  • if the class specified by text_span_class is not found within the selected objects, then no actions will be taken against the incompletely defined objects
  • if a different class name is desired for stylistic or programmatic reasons, a new, valid string can be specified

e_span_class

  • if an ellipsis_string is displayed at the tail end of the selected object’s text due to truncation of that text, then it will be displayed wrapped within a span associated with the class defined by e_span_class and immediately following the text_span_class‘ span
  • just like text_span_class, a different, valid class name can be specified

whole_word

  • when ThreeDots is fitting the provided text to the max_rows within the container object, this boolean setting defines whether or not the last word can be truncated to maximize the fit of the text within max_rows
  • if true, then don’t truncate any words and the ellipsis can ONLY be placed after the last whole word that fits within the provided space

e.g.

one time a duck flew
a frog shaped kite

…could become…

one time a duck flew
a (click for more)

  • if false, then maximize the text within the provided space, allowing the PARTIAL display of words before the ellipsis

e.g.

(continuing from the prior example)

one time a duck flew
a fr (click for more)

allow_dangle

  • a dangling ellipsis is an ellipsis that typically occurs due to words that are longer than a single row of text, resulting, upon text truncation, in the ellipsis being displayed on a row all by itself

e.g.

one time a duck flew floopydoopydoppydoodoodoodoo

… could become with allow_dangle:true …

one time a duck flew

  • if allow_dangle is set to false, whole_words is overridden ONLY in the circumstances where a dangling ellipsis occurs and the displayed text is adjusted to minimize the occurrence of such dangling of the ellipsis

e.g.

(continuing from the prior example)

one time a duck flew
floopydoopydoppyd…

alt_text_e

  • alt_text_e is a shortcut to enabling the user of the product that made use of ThreeDots to see the full text, prior to truncation, on mouse-over of the ellipsis
  • if the value is set to true, then the ellipsis span’s title property is set to the full, original text (pre-truncation) allowing the text to be seen by mousing over the ellipsis, if present
  • if the value is set to false, then the title value is left unaffected
  • this feature can be used in place of, or in conjunction with, additional styles or desired behaviors associated with mouse interactions of the selected object(s)
  • alt_text_e usage is not required to define your own custom interactions

alt_text_t

  • alt_text_t is a shortcut to enabling the user of the product that made use of ThreeDots to see the full text, prior to truncation, on mouse-over of the ellipsized text
  • if the value is set to true AND the ellipsis is displayed, then the text span’s title property is set to the full, original text (pre-truncation) and the text can be seen by mousing over the truncated text, if  the ellipsis is present
  • if the value is set to false, then the title value is left unaffected
  • this feature can be used in place of, or in conjunction with, additional styles or desired behaviors associated with mouse interactions of the selected object(s)
  • alt_text_t usage is not required to define your own custom interactions

Get It

You can download ThreeDots, dual licensed under GPL and MIT, from…

jQuery Repository
http://plugins.jquery.com/project/ThreeDots

Git
Public Clone URL: git://github.com/theproductguy/ThreeDots.git
GitHub: http://github.com/theproductguy/ThreeDots

Zip
http://plugins.jquery.com/files/jQuery.ThreeDots_source-bundle_1.0.10_20100125.zip

Demo

http://theproductguy.com/threedots/threedots.demo.html

Known Issues

  • None

Release Notes

Version 1.0 – 2009.10.28
Initial release.

Version 1.0.1 – 2009.10.28
[FIXED] num_row variable storage would result in erroneous calculations on variable padded and sized containers

Version 1.0.3 – 2009.10.30
[FIXED] optimized underlying algorithms for the significant improvement of ThreeDots’ performance/speed via private pre-processing function the_bisector()
[UPDATE] long word overflow logic more robust
[UPDATE] started putting versioning information in the minified plugin

Version 1.0.4 – 2009.12.29
[FIXED] bug in bisector was incorrectly truncating lines <= max_rows limit (thanks Giuseppe)

Version 1.0.5 – 2010.01.02
[FIXED] handle ‘em’ values returned where previously assumed always ‘px’ returned (for Chrome)

Version 1.0.6 – 2010.01.06
[FIXED] fixed saving of saved original text (thanks Yvo)

Version 1.0.7 – 2010.01.08
[FIXED] edge condition concerning super long words

Version 1.0.9 – 2010.01.22
[UPDATE] confirmed compatible with jQuery 1.3 and 1.4
[FEATURE] added Chrome compatibility

Version 1.0.10 – 2010.01.25
[FIXED] re-fixed 1.0.6

If you find this useful, or have any questions, ideas, or issues, leave a comment.

Enjoy!

Jeremy Horn
The Product Guy

47 Responses to “ThreeDots”

  1. Tweets that mention ThreeDots « The Product Guy -- Topsy.com Says:

    [...] This post was mentioned on Twitter by Dion Almaer, Rick Blalock. Rick Blalock said: RT @dalmaer: ThreeDots is a nice jQuery plugin to help you get the right ellipsis treatment that your UI needs http://tpgblog.com/threedots/ [...]

  2. Maarten Says:

    Hi,

    This plugin does not work on the latest Google Chrome (4.0.249.43)

    Greetings

  3. Yvo Nelemans Says:

    I’ve found a small bug in that the orginal text was cut off (seen when using alt_text_t or alt_text_e true).

    The orginal text is saved ‘after’ running it through you’re “preprocessor” resulting in cut of text being saved in the var init_text_span.
    Moving the line above the call to the function the_bisector fixes it.

    Thankx for this great utility.

  4. brunodbo Says:

    Hi,

    I posted two issues in your jquery.com issue queue, and was wondering if you had the time to look into these already.

    - Full text unavailable after truncating: http://plugins.jquery.com/node/12237 (this might be the same issue as Yvo Nelemens reported; I tried using v1.0.4 of your plugin, since I had only jQuery 1.0.x available)
    - HTML removed from truncated text: http://plugins.jquery.com/node/12238

    • Jeremy Horn Says:

      Regarding bug [12237] it has been corrected as of version 1.0.6 [available http://tpgblog.com/threedots & latest release at jquery repository]. Please let me know if you still experience problems after updating to the latest version.

      Regarding HTML removed: The behavior you describe is by design. Only text within the container is supported since one of the core assumptions is uniform line height for all of the lines/rows. Currently, you are allowed to style the text of the container to anything desired.

      BUT, handling HTML would definitely be very cool and I am brainstorming on how to possibly implement it in a compact and efficient manner. Would love to get your thoughts on desired behavior / implementation.

      Should anchor tags be able to be truncated? Anchor tags, due to truncation, could potentially be removed all together?

      Should nested HTML structures be supported? What HTML styles should be supported? [span] [b] [i] [u] …

      Remember, a table is valid HTML and I don’t see how that would be truncatable… but I am open to ideas / suggestions.

  5. umbata Says:

    hi,

    I’ve found out that if you set ‘vertical-align’ or ‘font-size’ on span element that is holding text to be truncated (ellipsis_text), the only thing you’ll end up with when setting max_rows to 1, is your ellipsis_string. However, it’s not the case with max_rows > 1.

    anyway, great plugin! thanks!

    • Jeremy Horn Says:

      You may want to check your width. Sounds like the width may be too narrow for the text. Also, just release 1.0.9 with Chrome support and more robust line count calculations. If you are still having difficulty I would be happy to check out the code to see what may be going on.

  6. Mike Jenkins Says:

    Just beeing trying to get your plugin to work but with no luck.

    I am trying to get it to work within an however stepping through the code it doesn’t seem to thing there is more than 1 row (I am trying to keep it to 1 row). On an example I tired the copy wrapped over 3 lines but the plugin still claimed it was one?

    • Jeremy Horn Says:

      Can you provide a sample of the HTML, JS, CSS that you are using to implement ThreeDots? What browser and version? Also, in addition to the code snippets, a link to the code would be great. I would be happy to take a peek and see what is going on.

  7. Martin Andersen Says:

    Hi Jeremy!

    When a text surrounded by a link is truncated by ThreeDots then the link disapears and only the text within stays. Is that a bug or have I misunderstood something.

  8. Nicola Says:

    Is it possible to detect if text is ellipsed or not?
    Like this:
    var obj = $(‘.ellips2line’).ThreeDots({max_rows: 2});
    if(obj.isEllipsed){
    alert(“text ellipsed”);
    }
    else{
    alert(“text NOT ellipsed”);
    }

    • Jeremy Horn Says:

      To know if text has been ellipsized I would compare the final text to the original text stored in the ‘ellipsis’ attribute OR simply check for the presence of the threedots_ellipsis span within the container object.

  9. jaan Says:

    Nice plugin.
    How can I update text after threedots was already called.
    After updating a database, I must update the new text in the list. In every list-item is a div where the text is truncated with threedots.
    After the update I cannot call threedots.update correctly. I end up with one letter (or none), or the entire text.
    Any idea’s?
    jaan

    • Jeremy Horn Says:

      What version of ThreeDots are you using? Which browser are you using? Can you provide me with HTML and JS that I can run on my local machine that can replicate the behavior you are describing?

  10. Tom Says:

    The plug-in works great in all but one case. If the content being truncated is a child of a parent that has display:none, the truncation shows only one letter. So, “Foo Is The Bar” becomes just “F”.

    I can hold off on applying the truncation until the content becomes visible but it’d be nice if it worked on hidden text.

    • Jeremy Horn Says:

      An object with display:none has no defined height and therefore can have no defined number of rows of text. To determine how many lines a piece of text takes up it cannot be set to have no height — the result of using display:none.

      If you want to truncate text before it is seen I recommend 1 of 2 options: (1) place the hidden object offscreen before moving the truncated text into visible place, or (2) instead of display:none, use visibility:hidden. For some of my personal implementations of the plugin I use various combinations of these two options depending on the desired user experience.

  11. Binyamin Says:

    Very cool man, but I would like to have an option to “Show/Hide”on the same plan and not on only the Mouseover ALT..

    • Jeremy Horn Says:

      Glad you like the plugin. The original text is always stored within the ‘threedots’ attribute. This is intentionally done to enable other developers to extend the core functionality. Using the text within ‘threedots’ you should have no problem enabling a show/hide function; with or without the mouseover alt being displayed.

      Hope that helps. When you implement it, I’d love if you’d share the URL and place where you implemented it so that others can learn from your implementation.

  12. cubesun Says:

    thank you for plugin!

    if you want it to work while window is resizing, use the code below:

    $(‘.text’).each(function(){
    var obj = $(this),
    txt = obj.find(‘.ellipsis_text’).text();

    obj.ThreeDots();

    $(window).resize(function(){
    obj.find(‘.ellipsis_text’).text(txt);
    obj.ThreeDots();
    });
    });

  13. phillip Says:

    Is it possible to set the max_rows to something like 1.3 or 1.5 – do you have any suggestions on modifying to make this possible?

    Love the plugin but need to being able to do 1.5 lines would ROCK!

    Thanks in advance for any tips.

    • Jeremy Horn Says:

      Can you elaborate on the use case? What would 1.5 lines be?

      • phillip Says:

        Basically, I have an inline element that sits at the end of the truncated text.

        Something like

        I am truncating the text within the anchor element and the em just slides in on the end. The problem is that 1 line is too short and 2 drops the em to a 3rd line.

        If it were possible to set the length to 1.5 lines then the em could be displayed inline next to the half line.

        Hope that helps and thanks for your suggestions.

        • phillip Says:

          Oops the form killed my formatting. this should be right after Something like. Sorry about that.

          <p /p>

          Sorry couldnt get it submit the full html.

          • Jeremy Horn Says:

            Can you provide me with a link to an example? I am not sure I m following you 100%.

            • phillip Says:

              Hi Jeremy.

              Thanks so much for trying to help. I was having trouble getting the html to show in my comments. I will try once again and hopefully this will go through.


              .....

              So right now I have threedots working on the anchor within the code above. I have it set to show 2 lines. The problem is that I have the em element there also. So I would like the a element to show on 1.5 lines so that there is still enough room for them em to sit on the second line and not be pushed down.

              Any suggestions would be greatly appreciate. Also feel free to email me at the address provided above if anything is still unclear.

              Thanks!

  14. Aaron M. Says:

    Hello, Jeremy:

    I am attempting to use ThreeDots inside a table cell but am having no luck. I have verified that ThreeDots is loading properly and that it is working correctly when applied to a div in the same document.

    I have tried changing the table’s layout to fixed, but that had no effect on ThreeDots behavior.

    Do you have any suggestions for further troubleshooting?

    Thanks!

  15. Zach Says:

    Jeremy,

    Thanks for a great plugin. I have a question for you about how to use this plugin inside of a jQuery ajax function. I have a “load more data” function on my site where I load more results like twitter or facebook.

    $.ajax({
    type: “POST”,
    url: ‘url’,
    success: function(value) {
    $(“#content”).append(value);
    $(“.ellipsis”).ThreeDots({max_rows:3});
    }
    });

    However, when I run this it takes the browser 1 minute to run through everything and the browser is not responsive during the process. Is there something wrong with my approach? Any help you could give would be much appreciated.

    Thanks,
    Zach

  16. Jack Says:

    Would there be a reason that the following would result in the ellipsis string disappearing? :

    $(“.class”).ThreeDots();

    on certain object hover -> $(this).find(“.class”).ThreeDots.update( { max_rows: 3 } );

    on out -> $(this).find(“.class”).ThreeDots.update( { max_rows: 2 } );

    The max rows are correctly changing but the ellipsis is disappearing… Any help would be greatly appreciated!

    • Jack Says:

      To clarify: the dots appear originally, but disappear once the rows are reduced back to 2 max.

      • Jeremy Horn Says:

        The ellipsis is only displayed when the text exceeds the max_rows.

        • Jack Says:

          I know. Let me clarify again:

          The text is three rows long. So in that first call on that first line, it truncates it so that there is an ellipsis and there are only two rows. On scrolling over one of the parent objects, the rows expand to three and all text is displayed. However, when the rows are put back to two, the ellipsis string no longer appears.

          I hope that makes sense. Thanks for your help!

          • Jeremy Horn Says:

            Can you send me a ZIP of an example of the code that I can run locally to check out next weekend? Also, please let me know browser and OS version you are using. Thanks.

  17. Roman Gavrilov Says:

    In one instance I see a text being trimmed, but ellipses string is not appended (I have ellipsis_string set to …).
    threeDots attribute is being set correctly.

    What could be possible reasons for this behavior?

    • Jeremy Horn Says:

      Please provide me with self contained source code that I can use to test locally. Also, please let me know within what browser, browser version, and OS you experienced this behavior.


Leave a Reply