Recently, a colleague asked me about such an interaction. When there is more text (more than 5 lines), the “full text” link appears, indicating that there is more content. After clicking it, it jumps to a new page

So, is there a way to implement this without using JS? I was interested when I saw it, and it looked like the previous article CSS implementation of multi-line text “unwrap” (juejin.cn) is a bit similar? However, the layout of this time is much simpler. After thinking about the interaction for a long time, I found that it can be perfectly realized, and it is a completely different way of thinking. Let’s have a look

A, layout,

On the layout of the piece there is nothing good to study, normal writing on the line, also do not need what float, the implementation of the following

<div class="wrap"> <p class="text">CSS <div class="wrap"> <p class="text">CSS < / div > <div class="wrap"> <p class="text">CSS A positive value will make it further away from the normal stream and adjacent blocks, while a negative value will make it closer. </div> > </div> > </div> > </div> > </div> > </div> > </div> >

Then add a bit of style, -webkit-line-clamp to achieve multi-line truncation

.wrap { background: #fff; border-radius: 8px; padding: 15px; box-shadow: 20px 20px 60px #bebebe, -20px -20px 60px #ffffff; } .text{ overflow: hidden; text-overflow: ellipsis; text-align: justify; display: -webkit-box; -webkit-line-clamp: 3; /* multiline over ellipse */ -webkit-box-orient: vertical; The line - height: 1.5; }

You can get something like this

Obviously, the links below are there all the time. So, how does CSS distinguish between these two situations?

Two, not perfect implementation

At first, I quickly thought of a way to do it, as follows

Use an element at the end of the text to mask the link below, which can be implemented with the pseudo element ::after.

.text::after{ content: ''; position: absolute; display: block; width: 100%; height: 50px; */ background: red; }

Results the following

Note the above implementation that ::after still follows the text because the top value is not set when absolute positioning is set. So in the case where the text is out of sight, the ::after is already out of view, so it doesn’t obscure the link below, which it actually is

Finally, replace the cover color with the same background color

.text::after{ background: inherit; /* Inherit the parent's background */}

Auto Expand Cover (codepen.io)

So why is it imperfect?

As careful friends may have noticed, even when the link is not displayed, it still takes up space below. When I gave this implementation to a colleague, it did

Three, the perfect realization

While there is nothing wrong with the function, it must be difficult to accept visually. Carefully compare the difference between the two cases, it is not difficult to find that the height of the two cases is not the same (😂 when the text is less, the default height of the link is less), so you can think about how to reduce the height of the container? Here I think of a negative margin, which is implemented as follows

First of all, absolute positioning is definitely no longer possible

.text::after{ content: ''; /*position: absolute; */ display: block; height: 50px; /* color: red; /* color: red; }

I can give you any height here, or I can give you 0, but I gave it 50px for color sake, and I added a background color

In this way, the effect with less text is as follows (more text is already out of bounds, not affected)

After setting a negative margin-top to ::after. Assuming the height of the link is 20, you will need to move up the height of the link by adding 20

.text::after{/* Mailbox */ margin-top: -70px; margin-top: -70px; 50 + 20 / * * /}

You can see that the height of the entire container has now been subtracted from the height of the links, as shown below

For now, however, the link below is still visible. At this point, you can just copy a text overlay, set the same style, and use the absolute positioning overlay (remember to add the background)

<div class="wrap"> <p class="text">CSS <div class="wrap"> <p class="text">CSS < / div > <div class="wrap"> <p class="text">CSS A positive value will make it further away from the normal stream and adjacent blocks, while a negative value will make it closer. </p> <p class="copy">CSS </p> <p class="copy">CSS </p> <p class="copy">CSS A positive value will make it further away from the normal stream and adjacent blocks, while a negative value will make it closer. </p><! > <a class="link"> </a> </div>
.text. Copy {/* same style */}.copy{position: absolute; left: 0; top: 0; width: 100%; height: 100%; }

The schematic principle is as follows

So this is a perfect implementation, although it has an extra layer of tags, but it can also be generated from pseudo-elements

<div class="wrap"> <p class="text" title=" margin-bottom "<div class="wrap"> <p class="text" title=" margin-bottom" A positive value will make it further away from the normal flow and adjacent blocks, while a negative value will make it closer. The margin-bottom property of >CSS is used to set the bottom margin of an element, allowing negative values to be set. A positive value will make it further away from the normal stream and adjacent blocks, while a negative value will make it closer. </div> > </div> > </div> > </div> > </div> > </div> > </div> >
.text::before{ content: attr(title); /* Other styles */}

Auto Expand Margin (codepen.io)

IV. Summary and explanation

Even if it is only a small interaction, but also contains a lot of CSS tips, there is no need to worry about compatibility, except line-clamp, other properties are fully compatible, summarize the following points

  1. Make full use of CSS masking and overflow hiding, many effects can be used
  2. Absolute positioning is still at the default text stream position when left or top is not used
  3. A negative margin changes the size of the container

Perhaps in the future there will be a text that goes beyond a pseudo-class, such as :trunk, so that many related interactions can be easily implemented. But before that, or can use a variety of camouflage simulation implementation, although some are not simple enough, but it is the fun of CSS unique, isn’t it? Finally, if you think it is good and helpful to you, please feel free to thumb up, bookmark, retweet