truncator css

by kontrach

HTML

<p data-items="10">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ratione, eos, dolore. Beatae totam sit quos, molestiae nulla inventore animi eum exercitationem ad placeat ducimus nostrum impedit consequuntur ipsam dignissimos esse.<span class="__end">&nbsp;</span>(20)
</p>

<p data-items="88" class="gradient">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ratione, eos, dolore. Beatae totam sit quos, molestiae nulla inventore animi eum exercitationem ad placeat ducimus nostrum impedit consequuntur ipsam dignissimos esse.<span class="__end">&nbsp;</span>
</p>

<!-- <button onclick="check()">Check if wisible</button> -->

CSS

body{
  padding: 50px;
}
p{
  position: relative;
  overflow-y: hidden;
  line-height: 1.2em;
  height: 2.4em;
  text-align: justify;
}
p.hidden:after{
  content: '... (' attr(data-items) ')';
  display: inline-block;
  bottom: 0;
  right: 0;
  position: absolute;
  background: white;
  text-align: right;
  /* width: 20%; */
  /* background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 50%); */
}

p.gradient.hidden:after{
  content: '(' attr(data-items) ')';
  display: inline-block;
  bottom: 0;
  right: 0;
  position: absolute;
  background: white;
  text-align: right;
  width: 8%;
  background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 50%);
}

JavaScript

var doc = document;
var global = window;
var end = document.querySelector('.__end');
var p = document.querySelector('p');
var gradient = document.querySelector('.gradient');
var gEnd = document.querySelector('.gradient .__end');

function handle() {
	const visibleP = isVisible(end);
  const visibleGradient = isVisible(gEnd);
  console.log('visible', visibleP, visibleGradient);
  if (visibleP) {
    p.classList.remove('hidden');
  } else {
    p.classList.add('hidden');
  }
  
  if (visibleGradient) {
    gradient.classList.remove('hidden');
  } else {
    gradient.classList.add('hidden');
  }
}

handle();

window.addEventListener('resize', handle);

function check() {
  console.log('check', isVisible(end));
}

window.check = check;

function isVisible(el, isStrict) {
	if (isElement(el)) {
		el.style.opacity = 'inherit'
		var rawOpacity = getStyle(el, 'opacity')

		var opacity = +rawOpacity
		if (opacity != rawOpacity) {
			opacity = 1 // can not check old browser
		}

		if (opacity > 0.09) {
			var offset = el.getBoundingClientRect()
			if (isPointInElement(el, offset.left, offset.top)) {
				if (!isStrict) return true
				// strict mode
				if (opacity > 0.89) {
					var x = offset.left + el.offsetWidth / 2
					var y = offset.top + el.offsetHeight / 2
					if (isPointInElement(el, x, y)) return true
				}
			}
		}
	}
	return false
}

window.isVisible = isVisible;

function getStyle(el, name) {
	if (global.getComputedStyle) {
		return getComputedStyle(el, null)[name]
	}
	if (el.currentStyle) {
		return el.currentStyle[name]
	}
}

function isElement(el) {
	if (el && 1 == el.nodeType) return true
	return false
}

function isPointInElement(el, x, y) {
	var target = doc.elementFromPoint(x, y)
	while (isElement(target)) {
		if (target == el) return true
		target = target.parentNode
	}
	return false
}