4

I need a way to truncate a string in the middle for a mobile app. The string has important info at the end that I always want to be visible. I haven't been able to find a CSS method to do it in the middle of the string, just the beginning or end.

I am working on a method to do this in JS, but I would think this has been addressed already and I don't want to re-invent the wheel. The thing I see becoming an issue is that I need it to be dynamic based on the screen size. I can't simply say if string.length > 100 then truncate. I need to see what will fit, then truncate, and make it listen for changes to size like if the orientation is changed.

hopper
  • 13,060
  • 7
  • 49
  • 53
John S
  • 573
  • 8
  • 22
  • CSS [`text-overflow: ellipsis`](https://developer.mozilla.org/en-US/docs/Web/CSS/text-overflow) does only work in the beginning or end, yes. Why (and *how*) do you want to split it in the middle? – Bergi Aug 06 '13 at 19:29
  • 2
    @Bergi sometimes it's important to show the beginning and end. I know we do it on our site where users will have a lot of domains. So they may have areallyreallyreallylongdomain.com and areallyreallyreallylongdomain.net. Cutting it off at the end would not help a user quickly determine which domain is which because they both would end up areallyreallyrea... – o_O Aug 06 '13 at 19:38

2 Answers2

5

With css, you can easily use ellipsis, but only at the end of the text.

However, there is a jQuery plugin called dotdotdot, which can do this.

Here's it's page: DotDotDot

One of their demo examples shows, how a long URL can be turned into
www.website.com/that/should/... /file.html


I spent some time trying to get this working properly, and it's still not quite perfect, but works pretty well.

// @param element    obtained with $("selector")
// @param spacer     ' ' for text, or '/' for links.
// @param position   number of words to leave at end
function doEllipsis(element, spacer, position) {
    $(element).data('ell-orig', $(element).html());
    $(element).data('ell-spacer', spacer);
    $(element).data('ell-pos', position);

    var pieces = $(element).html().split(spacer);
    if (pieces.length > 1) {

        var building = "";

        var i = 0;


        // for "position" to mean "fraction where to wrap" (eg. 0.6), use this:
        // for (; i < pieces.length*position; i++) {    

        for (; i < pieces.length-position; i++) {
            building += pieces[i] + spacer;
        }


        building += '<span class="ell">';

        for (; i < pieces.length; i++) {
            building += pieces[i] + spacer;
        }

        building += '</span>';

        $(element).html(building);

        $(element).dotdotdot({
            after: 'span.ell',
            wrap: 'letter'
        });
    }
}

// use to redraw after the size changes etc.
function updateEllipsis(element) {
    var orig = $(element).data('ell-orig');
    var spacer = $(element).data('ell-spacer');
    var pos = $(element).data('ell-pos');

    $(element).trigger("destroy");
    $(element).empty();

    $(element).html(orig);

    doEllipsis(element, spacer, pos);
}

Here's a fiddle of this example (it uses a copy hosted on my dropbox, so it's quite sure that it won't work forever).

It is responsive (to some extent, anyway), and puts the ellipsis exactly where you tell it to.

MightyPork
  • 18,270
  • 10
  • 79
  • 133
  • 1
    Could you please make an example for how to use dotdotdot so that it cuts the text *in the middle*? – Bergi Aug 06 '13 at 19:33
  • I specifically mentioned this and said it wont work. why is it being upvoted? – John S Aug 06 '13 at 19:37
  • @Bergi there's an example on their site for that – jcollum Aug 06 '13 at 19:39
  • 1
    @JohnS I don't see where you mentioned DotDotDot and that appears to do exactly what you want. – jcollum Aug 06 '13 at 19:40
  • @JohnS the reason for the upvotes, for better or for worse, people don't really care about the problem at hand, just what they would do or what solves their personal problem. I agree, answers should be tailored for the problem at hand, but that's not what happens many times here. – o_O Aug 06 '13 at 19:40
  • I made an example as requested. Please calm down, I don't get what's all this fuss about. – MightyPork Aug 06 '13 at 19:47
  • @jcollum that was edited after I made my comment. It happens all the time. I didnt make a big deal just mentioned it as many people seem to be in a rush to post and dont read the entire question. That is the reason that I dont have many points. I take the time to read and research before half answering. – John S Aug 06 '13 at 19:57
  • good link though, thanks. Looks like it will work but ill have to see what the performance is like and if its worth including in my project. – John S Aug 06 '13 at 19:59
  • I am still working on the fiddle, if you are interested. Getting quite good results, but it isn't yet quite what you want. – MightyPork Aug 06 '13 at 20:07
  • @john-s, check the fiddle now. It took me some effort, but finally I think it does pretty much the thing you wanted. It is also responsive, if you call the update function to redraw it. – MightyPork Aug 06 '13 at 20:18
1

How I would do it is...

Choose a monospace font so each character is the same width. Then figure out the width of each character at the font-size you wish. Then figure out, dynamically, how many characters you can fit inside the element or window at hand; that will be the max. Then you can use that max number in your truncation function which would make the new string length max minus 4 (subtract 3 for "..." and 1 so the last character doesn't accidentally slide offscreen).

Joe Simmons
  • 1,828
  • 2
  • 12
  • 9