Flexible overflow handling with CSS and JavaScript

Updated . Posted . Visible to the public.

You can use text-overflow to truncate a text using CSS but it does not fit fancy requirements.

Here is a hack for the special case where you want to truncate one of two strings in one line that can both vary in length, while fully keeping one of them. See this example screenshot where we never want to show an ellipsis for the distance:

Flexible overflow with optional ellipsis

You can try pretty hard, but there is no cool way with just using floats etc. Margins set in the CSS only work when one of the elements always has a fixed width. This is the result of a journey through that and more, ending up with a jQuery solution.

For it to work, just use the following structure and classes:

<li class="overflow_container">
  <a href="#" class="overflow_truncate">A very long city name</a>
  <span class="overflow_keep">
    (23 miles)
  </span>
</li>

This is the Sass that goes along with it, providing a fallback case for visitors without JavaScript that does regular text-overflow magic:

.overflow_container
  white-space: nowrap
  overflow: hidden
  text-overflow: ellipsis

Here is the code that makes the result pretty, using jQuery:

$(this).find('.overflow_container').each(function() {
  var truncate = $(this).find('.overflow_truncate');
  var keep = $(this).find('.overflow_keep');

  if (truncate && keep) {
    truncate.css('text-overflow', 'ellipsis');
    truncate.css('overflow', 'hidden');

    $.each([ truncate, keep ], function(index, self) {
      $(self).css('float', 'left');
      $(self).css('white-space', 'nowrap');
    });

    keep.html('&nbsp;' + $.trim(keep.html()));

    var keepWidth = keep.outerWidth();
    var containerWidth = $(this).outerWidth();

    truncate.css('max-width', (containerWidth - keepWidth) + 'px');
  }
});

Mind the following:

  • The non-breaking space is prepended to the second element because that one becomes floating. Since that would discard any whitespace between the two elements, we are adding the space (non-breaking to force it appear) that would usually separate them.
  • We're trimming the HTML of the element that should not be truncated so that we don't end up with nsbp + space, causing 2 spaces width.
  • Wrap the code in our unobtrusive JavaScript helper or another way it's run once the DOM is loaded.
Arne Hartherz
Last edit
Attachments
License
Source code in this card is licensed under the MIT License.
Posted by Arne Hartherz to makandra dev (2012-02-07 18:06)