]> git.ardis.lu - css-for-line-clamp-ellipsis/commitdiff
Replace getLineHeightInPx with pseudo element with 1lh height
authorArdis Lu <ardisglu@gmail.com>
Wed, 29 Jan 2025 04:19:18 +0000 (20:19 -0800)
committerArdis Lu <ardisglu@gmail.com>
Wed, 29 Jan 2025 04:19:18 +0000 (20:19 -0800)
index.html

index f7adc0e0e575bd6629d66c771d615bd4f937f844..c9f11bf67be63bde0548fcd3f23ed9ada4beeb50 100644 (file)
       -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">
@@ -278,11 +278,10 @@ new ResizeObserver(_ => {
         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>
@@ -295,10 +294,9 @@ new ResizeObserver(_ => {
 }</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>
 
@@ -310,6 +308,9 @@ new ResizeObserver(_ => {
   -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) {
@@ -320,21 +321,12 @@ new ResizeObserver(_ => {
   }
 }
 
-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">
@@ -366,26 +358,19 @@ new ResizeObserver(debounce(() => {
       }
     }
 
-    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
This page took 0.038534 seconds and 4 git commands to generate.