How can I check whether line-clamp is enabled?

Viewed 10204

I have a dynamic text in a span. I would like to use line-clamp: 2.

In that case there are max. 2 lines of text and the rest is truncated by ….

That works with:

  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;

My problem: If the content is truncated, a tooltip should be displayed. How can I detect whether the text is clamped?

The height of the element is the same, innerHTML is same... I have no further idea...

3 Answers

Detecting CSS line-clamp by javascript can be made by comparing the scrollHeight and the clientHeight of the "clamped" element.

The "true" height of the element is clipped by the overflow: hidden CSS property, but the DOM property scrollHeight will report the full height, while the clientHeight reports the rendered height.

enter image description here

The below example shows a clamped text.
Try hovering it to see if detection logged. (text is editable)

const isTextClamped = elm => elm.scrollHeight > elm.clientHeight

const onMouseEnter = elm => {
  console.clear()
  console.log( isTextClamped(elm) )
}
p {
  width: 200px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  resize: both; /* allowing resize for this demo only */
}
<p contenteditable spellcheck="false" onmouseenter="onMouseEnter(this)">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. 
</p>

Here's a Codepen which illustrates this live

You can check for the elements scrollHeight exceeding the clientHeight:

function multiLineOverflows() {
    const el = this._element.nativeElement;
    return el.scrollHeight > el.clientHeight;
}

A simple solution based on getClientRects().length that works for me.

$('.text-inline').each(function() {
  var textLineCount = $(this)[0].getClientRects().length;
  var lineClampValue = $(this).parent().css('-webkit-line-clamp');
  if (textLineCount > lineClampValue) {
    $(this).parent().addClass('cut');
  }
});
.text-block {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.text-block.expand {
  -webkit-line-clamp: initial;
}

.show-text {
  display: none;
}

.cut+.show-text {
  display: initial;
}

.expand+.show-text {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
<div class="text-block">
  <span class="text-inline">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore   magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</span>
</div>
<button class="show-text" onclick="$(this).prev().addClass('expand')">Read more</button>

Related