Reduce HTML text until it exceeds its container

1

I am trying to find a method that reduces a text HTML until it does not exceed the size of its container with overflow hidden . The text can have different fonts, letter sizes or line height, so it is very likely that the last line is cut in half, this is what I want to avoid. I found this question , but the solution is made to handle only special characters like these <>& . I've also found this one but it's too complicated and it does not work very well when the HTML is Too complex. Some solutions are only for WebKit or do not work efficiently with any type of text.

Here I leave the code that I have made so far (it is as ineffective as the previous ones that I have found), I have only placed it to make it clear that I have been working on it and I have not come looking for an answer without having thought about it a lot. I do not want this code to be revised but only to see what path I have taken. This code is capable of doing more than 1000 iterations and take several seconds depending on the HTML and the length of it and taking into account that in my application the container will change size very often this code would make it unusable.

Does anyone know of any quick and effective method to achieve this?

  

NOTE: My texts HTML only contain TEXT_NODEs and ELEMENT_NODEs (excluding scripts and styles ), I do not need to handle other types of nodes at the moment. p>

function reduceHTMLText (container) {

    var longer = false; 
    var reg = /^([\s\S]+?)\s*\.+$/;
    var regpunt = /^(.*?)[,;\:\.]$/;

    var isOverflow = function () {
        return container.scrollHeight > container.clientHeight;
    };

    var reduce = function (element) {

        var nodes = element.childNodes;

        if (nodes.length === 0) {

            longer = isOverflow();

            if (longer) { reduce(container); }

            return;

        }

        var last = nodes[nodes.length - 1];

        //---Depend of the node type
        switch (last.nodeType) {

            //---If the node is a text
            case 3:

                var str = last.data.replace(reg, "$1");
                var words = str.split(" ");

                //---If the words array has more than five words
                if (words.length > 5) {

                    words = words.slice(0, -5);

                    words[words.length - 1] = words[words.length - 1].replace(regpunt, "$1");

                    last.data = words.join(" ") + "...";

                } else {

                    last.parentNode.removeChild(last);

                }

                longer = isOverflow();

                if (longer) { reduce(element); }

            break;

            //---If the node is an element node
            case 1:

                if (last.childNodes.length) {

                    reduce(last);

                } else {

                    last.parentNode.removeChild(last);

                    longer = isOverflow();

                    if (longer) { reduce(element); }

                }

            break;

        }

    };

    longer = isOverflow();
    
    if (longer) { reduce(container); }

}

var container = document.querySelector(".container");

reduceHTMLText(container);
.container {
    background-color: #EEE;
    height: 170px;
    overflow: hidden;
    width: 500px;
}
<div class="container">
    <p style="text-align: left;">
        Vestibulum imperdiet ipsum nec urna ornare, quis malesuada odio viverra. Etiam mollis dolor lacus, ac cursus leo aliquam ut. Etiam eu elit in <strong>massa egestas <em>interdum ut</em> vel magna</strong>. Suspendisse nisl velit, bibendum id hendrerit at, maximus vitae neque. Integer varius sed ante quis porta. Aenean venenatis pellentesque semper. Etiam a quam ut mauris imperdiet vehicula tristique id lacus. <a href='#'>Aliquam lacus metus, mattis a viverra a, <strong>convallis sit amet diam</strong>. In dignissim lorem</a> sit amet, consectetur adipiscing elit. Cras non sem laoreet, tristique felis id, fringilla mi. Fusce sit amet iaculis enim. In malesuada risus eu urna interdum gravida. <strong>Praesent malesuada felis et mi gravida</strong>, at <em>interdum nunc sollicitudin. Quisque <strong>ultrices nibh</strong> in malesuada tempus</em>. Donec tempus efficitur maximus. Praesent ac lacinia odio. Maecenas vel nunc condimentum, luctus diam ac, molestie purus. Cras non tempor magna. Nulla et eros in nunc iaculis eleifend vel at nisi. <strong>Castro pero normal</strong> Aenean quis ultricies arcu, non volutpat neque. Aliquam at justo sed nisi malesuada lobortis eu ut risus. Fusce at enim quis dolor dignissim gravida vel a felis <span class="soleil-label">text paloma samona</span> is cube rubick <a href="http://google.com">because is impossible to</a> mantain the text in a long way.
    </p>
    <p style="text-align: center;">
        <div class='special'>
            <span class="soleil-cta-button-pink">
                <a href="http://google.com" class="soleil-cta-button-pink">NO REGRETS</a>
            </span>
        </div>
    </p>
</div>
    
asked by ElChiniNet 26.02.2017 в 04:46
source

1 answer

0

I propose a solution that does not involve the use of JavaScript, only css.

You define the number of lines you want to show in -webkit-line-clamp . The line size line-height . The size of the font in font-size . In height you put each of these values multiplying between them. It is a simple solution that can help you in many cases without having to execute JS.

.container {
    background-color: #EEE;
}
.truncate {
  display: block; /* Fallback for non-webkit */
  display: -webkit-box;
  max-width: 400px;
  height: 1.4*5*16; /* Fallback for non-webkit (line-height*number-lines*size )*/
  margin: 0 auto;
  font-size: 16px;
  line-height: 1.4;
  -webkit-line-clamp: 5;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}
<div class="truncate container">
Vestibulum imperdiet ipsum nec urna ornare, quis malesuada odio viverra. Etiam mollis dolor lacus, ac cursus leo aliquam ut. Etiam eu elit in <strong>massa egestas <em>interdum ut</em> vel magna</strong>. Suspendisse nisl velit, bibendum id hendrerit at, maximus vitae neque. Integer varius sed ante quis porta. Aenean venenatis pellentesque semper. Etiam a quam ut mauris imperdiet vehicula tristique id lacus. <a href='#'>Aliquam lacus metus, mattis a viverra a, <strong>convallis sit amet diam</strong>. In dignissim lorem</a> sit amet, consectetur adipiscing elit. Cras non sem laoreet, tristique felis id, fringilla mi. Fusce sit amet iaculis enim. In malesuada risus eu urna interdum gravida. <strong>Praesent malesuada felis et mi gravida</strong>, at <em>interdum nunc sollicitudin. Quisque <strong>ultrices nibh</strong> in malesuada tempus</em>. Donec tempus efficitur maximus. Praesent ac lacinia odio. Maecenas vel nunc condimentum, luctus diam ac, molestie purus. Cras non tempor magna. Nulla et eros in nunc iaculis eleifend vel at nisi. <strong>Castro pero normal</strong> Aenean quis ultricies arcu, non volutpat neque. Aliquam at justo sed nisi malesuada lobortis eu ut risus. Fusce at enim quis dolor dignissim gravida vel a felis <span class="soleil-label">text paloma samona</span> is cube rubick <a href="http://google.com">because is impossible to</a> mantain the text in a long way.
</div>
    
answered by 27.02.2017 в 10:50