JSFiddle - React, Tailwind, and code Playground

HTML

<BODY>
    <div class="truncate">
        <h3 class="truncate_test_string_shoobodooh">Loremitis!</h3>
        <p class="truncate_test_string_shoobodooh">Lorem ipsum dolor sit amet, consectetur adipiscing elit.
        Vestibulum laoreet, <b class="truncate_test_string_shoobodooh">nunc eget laoreet sagittis</b>,
        quam <em>ligula sodales orci, congue imperdiet</em> eros tortor ac lectus.</p>
        <p>Duis <i>eget nisl orci.<br/> Aliquam mattis purus non mauris
        blandit id luctus felis convallis.
        Integer varius <span>egestas vestibulum</span>.
        Nullam a </i>dolor arcu, ac tempor elit. Donec.</p>
    </div>
</BODY>

CSS

body {
    font-family: Calibri, Arial;
    margin: 0px;
    padding: 0px;
}
a {
    color: #0254EB
}
a:visited {
    color: #0254EB
}
.truncate {
    width: 400px;
    background-color: #f0f0f0;
    margin: 10px;
}
a.morelink,
a.lesslink {
    text-decoration:none;
    outline: none;
}

JavaScript

/**
 * Script found at http://jsperf.com/html-truncate-by-javascript/3
 */
var Stack = function () {
    this.items = [];
};

Stack.prototype = {
    size: function () {
        return this.items.length;
    },

    push: function (key) {
        this.items.push(key);
    },
    pop: function () {
        return this.items.pop();
    },
    /**
     * dump all close tags and append to truncated content while reaching upperbound
     */
    dumpCloseTag: function () {
        var html = '',
            i, len, tag;
        for(i = 0, len = this.size(); i < len; ++i) {
            tag = this.pop();
            html += '</' + tag.tag + '>';
        }
        return html;
    }
};

var stack = new Stack();

/**
 * HTML-Truncate Utility
 * This utility truncates html text and keep tag safe(close properly)
 */
function truncate(str, maxLength) {
    var content = '',       // traced text
        total = 0,          // record how many characters we traced so far
        matches = true,
        result, index, tag, tail;
    while(matches) {
        // find tags
        matches = /<\/?\w+(\s+\w+="[^"]*")*>/g.exec(str);
        if(!matches) break;
        var result = matches[0],
            index  = matches.index;
        // overceed, dump everything to clear stack
        if (total + index > maxLength) {
            content += str.substring(0, maxLength - total);
            content += stack.dumpCloseTag();
            break;
        } else {
            total += index;
            content += str.substring(0, index);
        }
        if (-1 === result.indexOf('</')) {
            tail = result.indexOf(' ');
            tail = (-1 === tail) ? result.indexOf('>') : tail;
            stack.push({
                tag: result.substring(1, tail),
                html: result
            });
        } else {
            stack.pop();
        }
        content += result;
        str = str.substring(index + result.length);
    }
    return content;
}
/**
 * end script
 */
 
/**
...