-webkit-box-orient: vertical;
-webkit-line-clamp: var(--lines);
overflow: hidden;
+
+ &::after {
+ height: 1lh;
+ }
}
.height-resizable {
-webkit-box-orient: vertical;
-webkit-line-clamp: var(--lines);
overflow: hidden;
+ &::after{
+ height: 1lh;
+ }
}</code></pre>
<p>And this JavaScript:</p>
- <pre><code class="language-javascript">function getLineHeightInPx(elem) {
- const temp = document.createElement('div');
- temp.textContent = '0';
- elem.insertAdjacentElement('beforeend', temp);
- const h = temp.scrollHeight;
- temp.remove();
- return h;
-}
-
-const elem = document.querySelector('.dynamic-line-clamp');
-new ResizeObserver(_ => {
- elem.style.setProperty('--lines', Math.floor(elem.clientHeight / getLineHeightInPx(elem)));
+ <pre><code class="language-javascript">const elem = document.querySelector('.dynamic-line-clamp');
+const lh = Number(getComputedStyle(elem, '::after').getPropertyValue('height').slice(0, -2));
+new ResizeObserver(() => {
+ const lines = Math.round(elem.clientHeight / lh);
+ elem.style.setProperty('--lines', lines);
}).observe(elem);</code></pre>
<p>Try adjusting the height:</p>
<div class="height-resizable-container">
If your paragraph's height is dynamic, it's useful to add some JavaScript to snap the paragraph's height to a multiple of
its <code>line-height</code> whenever the paragraph is resized. To do so, update <code>ResizeObserver</code>:
</p>
- <pre><code class="language-javascript">new ResizeObserver(_ => {
- const lineHeight = getLineHeightInPx(elem);
- const lines = Math.floor(elem.clientHeight / lineHeight);
+ <pre><code class="language-javascript">new ResizeObserver(() => {
+ const lines = Math.round(elem.clientHeight / lh);
elem.style.setProperty('--lines', lines);
- elem.style.setProperty('height', `${lines * lineHeight}px`);
+ elem.style.setProperty('height', `${lines * lh}px`);
}).observe(elem);</code></pre>
<p>It's also best to debounce the observer for better performance and to prevent the observer from fighting with
the user for control over the element's height while the user is resizing it. Using this basic debounce function:</p>
}</code></pre>
<p>You can update the observer to cancel if another event is fired within 200 milliseconds:</p>
<pre><code class="language-javascript">new ResizeObserver(debounce(() => {
- const lineHeight = getLineHeightInPx(elem);
- const lines = Math.floor(elem.clientHeight / lineHeight);
+ const lines = Math.round(elem.clientHeight / lh);
elem.style.setProperty('--lines', lines);
- elem.style.setProperty('height', `${lines * lineHeight}px`);
+ elem.style.setProperty('height', `${lines * lh}px`);
}, 200)).observe(elem);</code></pre>
</section>
-webkit-box-orient: vertical;
-webkit-line-clamp: var(--lines);
overflow: hidden;
+ &::after{
+ height: 1lh;
+ }
}</code></pre>
<p>And the final JavaScript:</p>
<pre><code class="language-javascript">function debounce(fn, wait) {
}
}
-function getLineHeightInPx(elem) {
- const temp = document.createElement('div');
- temp.textContent = '0';
- elem.insertAdjacentElement('beforeend', temp);
- const h = temp.scrollHeight;
- temp.remove();
- return h;
-}
-
const elem = document.querySelector('.dynamic-line-clamp');
+const lh = Number(getComputedStyle(elem, '::after').getPropertyValue('height').slice(0, -2));
new ResizeObserver(debounce(() => {
- const lineHeight = getLineHeightInPx(elem);
- const lines = Math.floor(elem.clientHeight / lineHeight);
+ const lines = Math.round(elem.clientHeight / lh);
elem.style.setProperty('--lines', lines);
- elem.style.setProperty('height', `${lines * lineHeight}px`);
+ elem.style.setProperty('height', `${lines * lh}px`);
}, 200)).observe(elem);</code></pre>
<p>And here it is in action!</p>
<div class="height-resizable-container">
}
}
- function getLineHeightInPx(elem) {
- const temp = document.createElement('div');
- temp.textContent = '0';
- elem.insertAdjacentElement('beforeend', temp);
- const h = temp.scrollHeight;
- temp.remove();
- return h;
- }
-
const elem = document.querySelector('#basic-observer');
- new ResizeObserver(_ => {
- elem.style.setProperty('--lines', Math.floor(elem.clientHeight / getLineHeightInPx(elem)));
+ const lh = Number(getComputedStyle(elem, '::after').getPropertyValue('height').slice(0, -2));
+ new ResizeObserver(() => {
+ const lines = Math.round(elem.clientHeight / lh);
+ elem.style.setProperty('--lines', lines);
}).observe(elem);
const elem2 = document.querySelector('#full-observer');
+ const lh2 = Number(getComputedStyle(elem2, '::after').getPropertyValue('height').slice(0, -2));
new ResizeObserver(debounce(() => {
- const lineHeight = getLineHeightInPx(elem2);
- const lines = Math.floor(elem2.clientHeight / lineHeight);
+ const lines = Math.round(elem2.clientHeight / lh2);
elem2.style.setProperty('--lines', lines);
- elem2.style.setProperty('height', `${lines * lineHeight}px`);
+ elem2.style.setProperty('height', `${lines * lh2}px`);
}, 200)).observe(elem2);
// Insert "Copy to clipboard" icon button to all code blocks