javascripthtmlcssoverflowellipsis

HTML text-overflow ellipsis detection


I have some elements on my page which have the CSS rules white-space, overflow, text-overflow set, so that overflowing text is trimmed and an ellipsis is used.

div {
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;

  border: 1px solid black;
  width: 150px;
  margin: 5px;
  padding: 5px;
  font-family: sans-serif;
}
<div>
  <span>Normal text</span>
</div>
<div>
  <span>Long text that will be trimmed text</span>
</div>

Is there any way I can use JavaScript to detect which elements' contents are overflowing?


Solution

  • Once upon a time I needed to do this, and the only cross-browser reliable solution I came across was hack job. I'm not the biggest fan of solutions like this, but it certainly produces the correct result time and time again.

    The idea is that you clone the element, remove any bounding width, and test if the cloned element is wider than the original. If so, you know it's going to have been truncated.

    For example, using jQuery:

    var $element = $('#element-to-test');
    var $c = $element
               .clone()
               .css({display: 'inline', width: 'auto', visibility: 'hidden'})
               .appendTo('body');
    
    if( $c.width() > $element.width() ) {
        // text was truncated. 
        // do what you need to do
    }
    
    $c.remove();
    

    I made a jsFiddle to demonstrate this, http://jsfiddle.net/cgzW8/2/

    You could even create your own custom pseudo-selector for jQuery:

    $.expr[':'].truncated = function(obj) {
      var $this = $(obj);
      var $c = $this
                 .clone()
                 .css({display: 'inline', width: 'auto', visibility: 'hidden'})
                 .appendTo('body');
    
      var c_width = $c.width();
      $c.remove();
    
      if ( c_width > $this.width() )
        return true;
      else
        return false;
    };
    

    Then use it to find elements

    $truncated_elements = $('.my-selector:truncated');
    

    Demo: http://jsfiddle.net/cgzW8/293/

    Hopefully this helps, hacky as it is.