Search code examples
javascripthtmlellipsiselasticlayout

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?


Solution

  • 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);