A Pen by Ream

This awesome code was written by ream-lab, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright ream-lab ©
  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

  <meta charset="UTF-8">
  <title>A Pen by  Ream</title>
      <link rel="stylesheet" href="css/style.css">



  <div class="text" data-lines="3"><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Vitae corporis iure reprehenderit sapiente eligendi esse quia provident. Aspernatur quisquam praesentium reprehenderit, culpa cum ullam, ex.</p>Eos expedita odit, similique tempora quod explicabo adipisci, soluta mollitia cum sequi autem. Aperiam <span>est similique voluptatem quibusdam aspernatur</span> porro quam ratione, exercitationem eos reprehenderit.</div>

    <script  src="js/index.js"></script>



/*Downloaded from https://www.codeseek.co/ream-lab/a-pen-by-ream-oWwZxg */
.text {
  width: 300px;
  font-family: Arial;
  font-size: 14px;
  line-height: 22px;

/*Downloaded from https://www.codeseek.co/ream-lab/a-pen-by-ream-oWwZxg */

var textNode = document.querySelector('.text');

var style = window.getComputedStyle(textNode);
var lineHeight = parseInt(style.getPropertyValue('line-height'), 10);
var lines = textNode.dataset.lines;
var currentHeight = textNode.offsetHeight;
var limit = textNode.contentText.length * (lines * lineHeight / currentHeight);


var excludeTags = ['br', 'hr', 'img'];

function getRestrictText(text) {
	var limit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 180;

	var fragment = document.createElement('div');
	fragment.innerHTML = text;

	var ctx = { limit: limit, nodesToRemove: [] };

	traverseAndCut(fragment, ctx);
	ctx.nodesToRemove.forEach(function (node) {
		return node.parentNode.removeChild(node);

	return fragment.innerHTML + '...';

function traverseAndCut(parent, ctx) {
	for (var i = 0, length = parent.childNodes.length; i < length; i++) {
		var node = parent.childNodes[i];

		if (node.nodeType === Node.TEXT_NODE) {
			var inlinedText = node.textContent.replace(/(\t|\n)+/g, '');

			if (ctx.limit < inlinedText.length) {
				var words = inlinedText.split(/\s+/);

				node.textContent = words.reduce(function (result, word) {
					ctx.limit -= word.length + 1;
					if (ctx.limit > 0) result.push(word);
					return result;
				}, []).join(' ').replace(/[\s,.]+$/, '');

				ctx.limit = 0;
			} else {
				node.textContent = inlinedText;
				ctx.limit -= inlinedText.length;

		if (node.nodeType === Node.ELEMENT_NODE) {
			if (~excludeTags.indexOf(node.nodeName.toLowerCase())) continue;
			traverseAndCut(node, ctx);
			if (!node.textContent.length) ctx.nodesToRemove.push(node);

function renderNode(tag, text) {
	var node = document.createElement(tag);
	node.textContent = text;
	return node;

var targetHTMLString = '\n\t<div class="c-entry-content">\n\t\t<p>Nintendo, we should try to remember, is a vast international corporation that wants nothing more than to liberate your hard-earned money from your wallet. But hell, if it isn\'t just slightly more endearing than its competitors. It\'s cute little touches like the secret message&nbsp;<a href="http://kotaku.com/the-nintendo-switch-pro-controller-hides-a-secret-messa-1792985504">discovered this weekend</a> hidden inside the&nbsp;<a href="http://www.theverge.com/circuitbreaker/2017/2/24/14699044/nintendo-switch-pro-controller-hands-on-preview">Switch\'s Pro Controller</a> \u2014 tiny text that reads "thx2 allgamefans!" \u2014 that keeps Nintendo cemented in the hearts of "allgamefans!" everywhere.</p>\n\t\t<p>It\'s not easy to find the message: you\'ll need to tilt the Switch Pro controller\'s right thumb stick down, and wiggle it around a bit. Pushing the stick in until it clicks is also a good idea that should, in the right light, show you the cute little note that seems to be printed on the circuit board below. If you still can\'t find it, Japanese Twitter users @y_beat and @geo_stream have provided handy visual hints.</p>\n\t</div>\n';

var resultHTMLString = getRestrictText(targetHTMLString);

var resultFragment = document.createElement('div');
resultFragment.innerHTML = resultHTMLString;

var resultTextString = resultFragment.textContent;
var resultTextStringLength = resultTextString.length;

var resultNode = document.createElement('div');

resultNode.appendChild(renderNode('p', 'Count: ' + resultTextStringLength));
resultNode.appendChild(renderNode('pre', resultTextString));
resultNode.appendChild(renderNode('pre', resultHTMLString));