9

Is it at all possible to hide the middle of overflown text instead of the end? Such as replacing the overflown text with periods.

I'm specifically talking about in a table now, but any possible way would be good to know.

So I mean shortening 112233445566778899 to 112...899 (or something similar) instead of 11223344

I don't know too much of JavaScript but if this is the only way let me know how and I'll figure out the rest with tutorials.

Amal Murali
  • 75,622
  • 18
  • 128
  • 150
LuukV
  • 203
  • 1
  • 11

5 Answers5

5

I've come up with a pure-JavaScript solution which combines Nick R's and alhoseany's answers together, whilst adding in a few extra bits of functionality to detect length and specify the number of characters required either side of the ellipsis.

With this method you do not need to know the number of characters that can fit in your container, it's all done automatically and can also be triggered when the window resizes.

JSFiddle demo.

Resize the result frame to see the results in action.

Result

This:

Initial Example

...becomes this:

Example

...or this:

Example 2

...or this!

Example 3

The Code

CSS

p {
    border: 1px dashed #000;
    position: relative;
    display: block;
    width: 50%;
}

p:before {
    content:attr(data-shortened);
    color: #000;
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
}

JavaScript

function shortenContent(content, chars) {
    /* chars here determines how many characters
     * we want on either side of the elipsis. */
    var chars = chars || 3; // Default is 3
    
    if (!content && !content.length)
        return;
    
    /* Loop through each content element and
     * shorten where necessary. */
    for (i = 0; i < content.length; i++) {
        var el = content[i],
            elementWidth = el.offsetWidth,
            textWidth = el.scrollWidth;
        
        /* If our element's width is less than
         * its content's width, we need to shorten. */
        if (elementWidth < textWidth) {
            var text = el.innerText;
            /* Set the data attribute for the CSS to use. */
            el.setAttribute(
              'data-shortened', text.slice(0,chars) +'...'+ text.slice(-chars)
            );
            el.style.color = 'rgba(0, 0, 0, 0)';
        }
        /* Otherwise, ensure non-shortened text is visible. */
        else {
            el.setAttribute('data-shortened', '');
            el.style.color = null;
        }
    }
}

How do I use it?

To use the above function, you simply need to pass in a collection of elements into the shortenContent function:

// Get the content we wish to shorten
var content = document.querySelectorAll('div p');

/* Trigger the function initially. */
shortenContent(content);
abcdefghijklmnopqrstuvwxyz    =>    abc...xyz

Specifying a different number of characters

If you want a different number of characters to appear before and after the ellipsis (e.g. abcd...wxyz instead of abc...xyz), you can pass in a number as a second argument into the shortenContent function:

/* Trigger the function initially. */
shortenContent(content, 4);
abcdefghijklmnopqrstuvwxyz    =>    abcd...wxyz

Window Resize example

This will fire the shortenContent function whenever the window (the JSFiddle result pane, in this case) changes size.

/* Fire the shorten function when the window resizes. */
window.onresize = function(event) {
    shortenContent(content);
};
Community
  • 1
  • 1
James Donnelly
  • 126,410
  • 34
  • 208
  • 218
4

Using Javascript, you could do something like this:

function shortenNum(num){

    if(num.length > 6){
        var first = num.slice(0, 3); 
        var last = num.slice(-3); 
        //console.log(first + "..." + last );
        alert(first + "..." + last );
    } else {
        alert(num)
    }
}

// should return 112...899
shortenNum("112233445566778899");
shortenNum("19999");
shortenNum("3536355");

It takes in a string, and grabs the first 3 characters and the last 3, then we can just concatenate them together, plus the ...

You could use substring as well instead of slice

JSFiddle Demo

edit: added a check for string length, anything over 6 characters should be shortened.

Nick R
  • 7,704
  • 2
  • 22
  • 32
  • Nice. Didn't see you already have answered. Have also an answer basedd on your concept. I hope it is ok. – Christian Gollhardt May 30 '14 at 13:37
  • But what if my number is only `123`? http://jsfiddle.net/qHALz/4/ You should add some length checking in there. – James Donnelly May 30 '14 at 13:37
  • As I said, it would be challenging if we consider all cases like a fluid container. Even here you are not considering fixed width. I am not sure whether OP is satisfied with this.. – Mr_Green May 30 '14 at 13:39
  • @JamesDonnelly Yeah I should probably work on my defensive coding :p – Nick R May 30 '14 at 13:39
  • @NickR I decided to go ahead and combine this answer with allhoseany's below: http://stackoverflow.com/a/23956645/1317805 – James Donnelly May 30 '14 at 14:21
3

Here is a anonymously Javascript Example

This is the Js (Based on Nick R's Comment)

$('.shortable').each(function(index) {
    //Get the Text
    var text = $(this).text();

    //Get the wanted Length
    var wantedLength = $(this).data('length')

    //Get the current Length
    var currentLength = text.length

    //If it should be shorten
    if (wantedLength < currentLength) {
        //Get Half Length
        var halfLength = Math.round(wantedLength / 2)

        //Get the Text Parts
        var first = text.slice(0, halfLength); 
        var last = text.slice(0-halfLength); 

        //Change the Text
        $(this).text(first + "..." + last);
    }
});

This is the Html (Look at the Attributes):

<p class="shortable" data-length="20">Lorem ipsum dolor</p>
<p class="shortable" data-length="20">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>

This is the Output:

Lorem ipsum dolor

Lorem ipsu... sit amet.    

And this is your Fiddle:

http://jsfiddle.net/qHALz/6/

And this is your additional Question

Is there a simple Js way of applying it on everything that would actually overflow and not on things that don't?

You can append the class shortable and the data-length Attribute to all those Elements.

For Example

<span class="shortable" data-length="20">Lorem Ipsum...</span>
<i class="shortable" data-length="20">Lorem Ipsum...</i>
<a class="shortable" data-length="20">Lorem Ipsum...</a>
Christian Gollhardt
  • 16,510
  • 17
  • 74
  • 111
  • 1
    :) Nice. A bit more flexible than mine. – Nick R May 30 '14 at 13:36
  • This is perfect. Is there a simple Js way of applying it on everything that would actually overflow and not on things that don't? – LuukV May 30 '14 at 13:42
  • 1
    Just add a class of `shortable` to the overflowing elements. So `4353453454543534` and the `.each` means it loops through all the elements with that class, and runs the function. – Nick R May 30 '14 at 13:47
  • @LuukV Edited, so it also work if the text is shorter then `data-length` (20) – Christian Gollhardt May 30 '14 at 13:48
2

With CSS, its not possible to clip or ellipse in mid text

Quoting W3C :

Existing behavior

According to the description of text-overflow at Mozilla and the definition in the current W3C CSS UI module spec there's currently only the possibility to clip strings at the beginning and their end.

Only Possible Solution is from JavaScript, this thread would help you:

Ellipsis in the middle of a text (Mac style)

Community
  • 1
  • 1
NoobEditor
  • 15,563
  • 19
  • 81
  • 112
2

there is a ways to do this with html and css:

you can use the css pseudo elements with content property to replace the numbers with any attribute content like title or data-numbers.

example:

<div class="target" data-numbers="112...899" ><span>112233445566778899</span></div>

.target span{
    display:none;
}
.target:before{
    content:attr(data-numbers);    
}

http://jsfiddle.net/cUrjH/

alhoseany
  • 761
  • 9
  • 28