BlaM BlaM - 6 months ago 61
HTML Question

Insert ellipsis (...) into HTML tag if content too wide

I have a webpage with an elastic layout that changes its width if the browser window is resized.

In this layout there are headlines (

h2
) that will have a variable length (actually being headlines from blogposts that I don't have control over). Currently - if they are wider than the window - they are broken into two lines.

Is there an elegant, tested (cross-browser) solution - for example with jQuery - that shortens the innerHTML of that headline tag and adds "..." if the text would be too wide to fit into one line at the current screen/container width?

Answer

I've got a solution working in FF3, Safari and IE6+ with single and multiline text

.ellipsis {
	white-space: nowrap;
	overflow: hidden;
}

.ellipsis.multiline {
	white-space: normal;
}

<div class="ellipsis" style="width: 100px; border: 1px solid black;">Lorem ipsum dolor sit amet, consectetur adipisicing elit</div>
<div class="ellipsis multiline" style="width: 100px; height: 40px; border: 1px solid black; margin-bottom: 100px">Lorem ipsum dolor sit amet, consectetur adipisicing elit</div>

<script type="text/javascript" src="/js/jquery.ellipsis.js"></script>
<script type="text/javascript">
$(".ellipsis").ellipsis();
</script>

jquery.ellipsis.js

(function($) {
	$.fn.ellipsis = function()
	{
		return this.each(function()
		{
			var el = $(this);

			if(el.css("overflow") == "hidden")
			{
				var text = el.html();
				var multiline = el.hasClass('multiline');
				var t = $(this.cloneNode(true))
					.hide()
					.css('position', 'absolute')
					.css('overflow', 'visible')
					.width(multiline ? el.width() : 'auto')
					.height(multiline ? 'auto' : el.height())
					;

				el.after(t);

				function height() { return t.height() > el.height(); };
				function width() { return t.width() > el.width(); };

				var func = multiline ? height : width;

				while (text.length > 0 && func())
				{
					text = text.substr(0, text.length - 1);
					t.html(text + "...");
				}

				el.html(t.html());
				t.remove();
			}
		});
	};
})(jQuery);