Anyone working at the large front end of a regular business requirement should have encountered a similar requirement, which is displayed in N lines and displayed at the end of a sentencean, click Showall, can be carried outPack upOperation.

The target

plan

Pure CSS scheme

  • 1. Perform the first step. If the number of rows reaches the requirement,…. is displayed I won’t go into this too much

<div class="desc">Silent you, the forest of bleak sunshine, the person that those you love, gentle so soft, ignorant I am fallen leaf desolate again abjection, see my residual enthusiasm, interlacing silence now, whistling and pass youth, silent you, even if give me a bright tomorrow</div>
Copy the code
   .desc {
    display: -webkit-box;
    -webkit-line-clamp: 3; // Display the maximum number of lines -webkit-box-orient: vertical;overflow: hidden;
    text-align: justify;
    font-size: 16px;
    line-height: 44px;
  }
Copy the code

  • 2. Display the expand/unwind button
<div class="desc">
    <button class="btn">an</button>Silent you, the forest of bleak sunshine, the person that those you love, gentle so soft, ignorant I am fallen leaf desolate again abjection, see my residual enthusiasm, interlacing silence now, whistling and pass youth, silent you, even if give me a bright tomorrow</div>
Copy the code
.btn {
    float: right;
    clear: both;
    background-color: #f00;
    border: none;
    color: #fff;
    line-height: 24px;
}
.desc {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-align: justify;
    font-size: 16px;
    line-height: 44px;
}
Copy the code

Use float to float the button into the text surround layout, but now we can see that the button is displayed in the upper right corner, which is not the desired position. How to get it down

The button moves to the lower right corner, but the text’s surround mode is not retained, and the text rendering area is cut. Margin can’t be satisfied because the space at the top of the document is still occupied by buttons, button elements are not removed from the document flow, and natural text cannot rerender white space.

  • 3. Keep the floating layout, let the button move down, and add an element to push the button down
    .btn {
     float: right;
     clear: both; // Clear the floatbackground-color: #f00;
     border: none;
     color: #fff;
     line-height: 24px;
    }
    .desc {
     display: -webkit-box;
     -webkit-line-clamp: 3;
     -webkit-box-orient: vertical;
     overflow: hidden;
     text-align: justify;
     font-size: 16px;
     position: relative;
     line-height: 44px;
    }
    .desc::before{
     content: ' ';
     float: right;
     width: 10px;
     height: 46px;
     background: # 000;
     overflow: hidden;
    }
    Copy the code

  • 4. Hidden mode makes use of pseudo classes to achieve UI restoration degree
    .desc::before{
        content: ' ';
        float: right;
        width: 0px;
        height: 46px;
        overflow: hidden;
    }
    Copy the code

  • 5. The button cannot be hidden automatically when the number of text lines does not overflow

Solution: class, the use of pseudo-class cover the way of camouflage

.desc::after {
    content: ' ';
    position: absolute;
    width: 100%;
    height: 100%;
    background: # 000;
}
Copy the code

Left top bottom right; Left Top enters the document stream by default

Optimization: pseudo-class background color and large background color, you can solve the problem

  • 6. Check the configuration to improve reusability
    // desc::before height is strictly dependent on font line height, which is equivalent to write dead configuration, poor reuse.
    // Height equals element 100% - button height - (row height - button height) /2
    Calc (100%-34px)
    
    // You will find that height :100% is not available in standard document flow. Can be broken through flex layoutModify the element node to add a negative class element <divclass="content">
        <div class="desc">
            <button class="btn">an</button>Silent you, sunshine bleak woods, those you love, gentle so soft, ignorant ME, it is a lonely leaf down and out, see my residual enthusiasm interpenetrating silence now, roaring youth, silent you, even if give me a brilliant tomorrow</div>
      </div>
    
     .content{
        display: flex; overflow: hidden; } at this point, the element height can be correctly retrieved, since calc is compatible, a better solution would beheight: 100% margin-bottom:-34px Performance is also friendlierCopy the code
  • 7. Complete implementation code
.content{
    display: flex;
    overflow: hidden;
  }
  .btn {
    float: right;
    clear: both;
    background-color: #f00;
    border: none;
    color: #fff;
    line-height: 24px;
  }
  .desc {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-align: justify;
    font-size: 16px;
    position: relative;
    line-height: 44px;
    word-break: break-all;
  }
  .desc::before{
    content: ' ';
    float: right;
    width: 0px;
    /* height: calc(100% - 32px); * /
    background: # 000;
    overflow: hidden;
    height: 100%;
    margin-bottom: -34px;
    /* Better performance, better compatibility (line-height-bTN height)/2 + BTN height */
  }

  .desc::after {
    content: ' ';
    position: absolute;
    width: 100%;
    height: 100px;
    background: #fff;
  }
Copy the code
<div class="content">
    <div class="desc">
    <button class="btn">an</button>Silent you, sunshine bleak woods, those you love, gentle so soft, ignorant ME, it is a lonely leaf down and out, see my residual enthusiasm interpenetrating silence now, roaring youth, silent you, even if give me a brilliant tomorrow</div>
  </div>
Copy the code
Sink as a business base component, complete flexibility to analyze the stylesheets in the code above
Text line height, use js to get the document. The defaultView. GetComputedStyle (el) [” line – height “]
The row height of the button is inherited directly

JS implementation scheme

let el = this.$el;

  let lineHeight = parseFloat(
    document.defaultView
      .getComputedStyle(el)
      ["line-height"].replace("px".""));let COMPAT_VALUE = 10; // take 10 as a buffer value to prevent different browsers from displaying different heights

  if (el.offsetHeight > lineHeight * this.maxLine + COMPAT_VALUE) {
    // The maximum row is exceeded and a collapse operation is required
    this.foldState = FOLDED;

    // Delay the expanded button to update to the page
    this.$nextTick(_= > {
      while (el.offsetHeight > lineHeight * this.maxLine + COMPAT_VALUE) {
        / / in order to deal with emoji delete, refer to http://www.alloyteam.com/2016/12/javascript-has-a-unicode-sinkhole/
        let tmpArray = Array.from(this.textEl.textContent);
        tmpArray.pop();
        this.textEl.textContent = tmpArray.join("");
        // console.log(this.textEl.textContent, el.offsetHeight)}}); }Copy the code
Implementation idea: throw all the ellipsis of the button that needs to be displayed into the parent dom element, compare the actual rendered height with the maximum height that can be displayed by loop calculation, and subtract the text content. Achieve a final high degree of consistency

# # # # # # # reference:

Juejin. Cn/post / 696390…

Juejin. Cn/post / 684490…