CSS advanced application of three methods to achieve multiline ellipsis example code

Time:2020-2-13

Preface

This is an old-fashioned demand, but there are still many people looking for solutions on the Internet, especially those in the top of search results, which only introduce the use of poor compatibility-webkit-line-clampThe plan.

If you read this article, it may mean that you just jumped from so many thousands of identical articles and wanted to find a better case. Congratulations, there is no better one, only the more inappropriate one. Of course, only if my article has enough traffic and can be topped can you have a chance to see it.

Here are three methods of multi line text truncation. Of course, the first one is what you want to vomit-webkit-line-clampPlan, do not want to see directly jump to the second way to start to see.

Use WebKit line clamp

Apply the following style to containers of multiline text


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

except-webkit-line-clampOther attributes are fixed, mainly displaying the object as an elastic expansion box model, and setting the arrangement of child elements of the expansion box object.

and-webkit-line-clampIt is used to control how many lines are omitted

Advantage:

  • Browser native support for omitting behavior, style looks comfortable
  • Easy to use

Disadvantages:

Look at the prefix of the attribute. This iswebkitKernel browser support, compatibility is not extensive.

 Usage scenarios

If you only aim at WebKit kernel browser or mobile terminal (most mobile browsers are WebKit kernel), this scheme is the best.

Using absolute positioning

In fact, this scheme is well understood. First of all, we reserve a space on the right side of a container for content to put ellipsispadding-right: 1em;To reserve space, why is 1em? An ellipsis is almost 1em. The EM unit is used to respond to the font size.

Use absolute positioning to locate the ellipsis in the lower right corner of the reserved space.

html

< div class = "wrap" > content < / div >

css

.wrap3 {
    position: relative;
    padding-right: 1em;
    /*Max height is several times that of line height. You can display as many lines as you want*/
    max-height: 3.6em;
    line-height: 1.2em;
    text-align: justify;
    overflow: hidden;
}

.wrap3:before {
    position: absolute;
    right: 0;
    bottom: 0;
    content: '...';
}

Effect (multi content):

In this way, the ellipsis will always exist. So to solve this problem, we use a square with the same color as the background to mask the ellipsis, so the key point is, how to know when to mask and when not?

Idea: the block used to block the ellipsis is also an absolute positioning, which is set on the right,right: 0ButbottomDo not set the value. If it is not set, the box will move with the actual height of the text content instead ofmax-heightThe height. In this case, when there is no need to omit (i.e. no more thanmax-height)When it happens to bebottom: 0The ellipsis will be blocked. When omitting (i.e. overmax-height)The ellipsis will be blocked, and it will beoverflow: hiddenIt’s hidden.

So the final plan is:

html

< div class = "wrap" > content < / div >

css

.wrap {
    position: relative;
    /*Line height and height should cooperate with each other. The number of lines displayed should be omitted, which is the multiple of line height*/
    line-height: 1.2em;
    max-height: 3.6em;
    /*This property is used to determine whether to set it according to the requirements. Because the padding right is set, more points are vacated. This value is generally the negative value of the padding right value*/
    /*margin-left: -1em;*/
    /*It's good to write this value as 1em, because the ellipsis takes up about 1em of space*/
    padding-right: 1em;
    text-align: justify;
    overflow: hidden;
}

.wrap:before {
    position: absolute;
    right: 0;
    bottom: 0;
    content: '...';
}

.wrap:after {
    position: absolute;
    right: 0;
    /*It's good to write 1em for width and height, because the ellipsis takes up about 1em of space to block the ellipsis, which is basically the same as the padding right of wrap*/
    width: 1em;
    /*Consistent with the actual row height of wrap*/
    height: 1.2em;
    content: '';
    /*It needs to be the same color as the background to block the ellipsis*/
    background-color: #fff;
}

Effect:

 

Advantage

  • Good compatibility, supported by major browsers
  • Adaptive height, do not write dead height, set more than how many lines to omit display
  • Adaptive width
  • Adaptive font size, font size will not affect the original requirements, that is, how many lines are required to be omitted will be omitted

shortcoming

  • The right side of the text will intentionally leave some space for the ellipsis
  • You need to consider the background color, because the after pseudo class uses the background color to hide the ellipsis

 Using float layout

This scheme may not be well understood by children’s shoes who do not have solid basic knowledge. If you just want to find a solution and don’t want to know the principle, you can go to see it directly

Before we talk about the plan, we need to understand such a phenomenon:

There’s a piece of HTML

<div class="wrap">
    < div class = "left" > float left < / div >
    < div class = "right1" > right float 1 right float 1 right float 1 right float 1 right float 1 right float 1 right float 1 right float 1 right float 1 right float 1 right float 1 right float 1 right float 1 right float 1 right float 1 right float 1 right float 1 right float 1 right float 1 right float 1 < / div >
    < div class = "right2" > right float 2 < / div >
</div>

Apply such a style

.wrap {
	height: 100px;
}
.left {
	float: left;
	width: 60px;
	height: 100%;
	background: pink;
}
.right1 {
	float: right;
	/*Full wrap divide left remaining width*/
	width: calc(100% - 60px);
	background: #95d9f8;
}
.right2 {
	float: right;
	background: yellow;
}

Normally, it will be displayed like this, which is also the expected situation that you can generally imagine:

The conditions for this normal phenomenon are:

  • .right1Not more than.leftHeight of (i.e. less content)
  • .right2Less than.right1Width

All right, let’s understand this situation. So next, we’re right.right1The next scene will occur when the content increases beyond the left floating height

Right float 2 is stuck in the lower left corner.

Ask me why? Well… It seems that you don’t have solid basic knowledge of float. It’s suggested to consolidate the basic knowledge. In fact, I can’t explain it. I only know that this is a normal performance of float.

The conditions for this phenomenon are:

  • .right1Over.leftHeight of (i.e. more content)
  • .right2Less than or equal to.leftWidth

Knowledge into demand realization

After understanding the above two scenarios, how can we use these knowledge to match the corresponding needs?

Suppose that the text content of right float 1 is the content we want to omit in multiple lines, and the content of right float 2 is the ellipsis (…). In this way, when the content is small, ellipsis is the first case, and when the content is large, it is the second case.

Is this kind of dynamic change like “when the text is less, it will not be omitted; when the text is more, it will be omitted”. On this basis, what we need to solve is that in the first case, the right float 2 is hidden, and in the second case, the right float 2 appears in the.wrapIn the lower right corner, the contents beyond the height are hidden.

To solve these problems, only useposition: relative;Relative positioning is enough..wrapParent container applicationoverflow: hidden;。 In the first case, navigate outside the parent container and hide it. In the second case, it is located in the lower right corner of the parent container.

Now, the focus of the solution is on how to accurately locate it (the next section). Before dealing with the positioning problem, first convert the current situation into the actual demand code:

<! -- replace the actual label with pseudo class elements for left float and right float 2 -- >
<div class="wrap">
    < div class = "text" > right float 1 < / div >
</div>
.wrap {
    height: 100px;
    /*Line height is used to control how many lines of text are displayed at most*/
    line-height: 20px;
    overflow: hidden;
}
.wrap:before {
    float: left;
    /*To be greater than or equal to the after element width*/
    width: 1.5em;
    height: 100%;
    content: '';
}
.text {
    float: right;
    /*Use negative marginleft to avoid blank space generated by before*/
    /*Because it's impossible for your parent container to have a blank on the left*/
    margin-left: -1.5em;
    /*With a negative value of marginleft, the width of the text container can be 100% of the width of the parent container*/
    width: 100%;
}
.wrap:after {
    float: right;
    /*Generally, the width of three points is about 1em, and the font size can be adaptive with em as the unit*/
    width: 1em;
    content: '...';
}

If you’re curious, why.textThey are all set up.width: 100%;It’s a long time:afterStill stuck:beforeWhat about the bottom? Because even if.textSet upmargin-left: -1.5em;, but in fact, it does not affect the original document flow situation. What should be is how to set a negative margin. What is affected is.textIts own rendering style.

How to locate

The solution to the location problem is based on the code in the previous section. The problems exposed at present are:

  1. When there is little content, i.e. no need to omit, the ellipsis is is displayed
  2. Ellipsis is hidden when there are many contents that need to be omitted

Solve the second problem first

Train of thought: put this:afterMove right to.wrapOn the right, move up to the last line.

useposition: relative;To control,topGood value.wrapOfline-heightThe actual value is the same, take a negative value. The key is the left value. How to get it can be displayed in the lower right corner.

If you know for sure.textIf the width of (e.g. 100px), actually setleft: 100px;OK, but in this case, the width can only be fixed, not adaptive. In order to achieve self-adaptive, the value of left should be taken as a percentage. What is the percentage? This is a tangle. Simply take 100%, and you will find that it will be moved out of the parent container.

If it happens to appear in the lower right corner, the initial position of the ellipsis must be.wrapOn the left, next to.wrapTalentleft: 100%Appears in the lower right corner.

Now the question is how to:afterIt happens to be.wrapTo the left. The following code may be a little difficult to understand for people with weak foundation (the new part is in the comments):

.wrap:after {
    float: right;
    /*Because margin is set below, the width value size here is not required*/
    width: 1em;
    content: '...';
    
    /*These two properties are set next to the left side of. Wrap*/
    /*This value should be the same as its own width, taking a negative value*/
    margin-left: -1em;
    /*This value should be the same as before width*/
    padding-right: 1.5em;
    
    /*This is where the ellipsis is located*/
    position: relative;
    left: 100%;
    /*Take a negative value as the row height actual value of the parent element wrap*/
    top: -20px;
}

As for setting the margin and padding values, it’s best if you can understand them. If you can’t understand them, I’ll try my best to explain them. In fact, it’s hard to say.

The first is applicationmargin-left: 1em;Because:afterWidth ratio:beforeIt’s smaller, so in line with the original float layout

Pink is left floating, blue red is right floating. If the width of red increases to the remaining space except pink, because there is not enough space in one line, blue will be squeezed to the right floating of line breaking. But if you set the blue margin left to be a negative value of its own width, then the space of a row will still have a position for it, which will become as follows

According to the above principle, themargin-left: 1em;Later,:afterIt goes back to the first line of the parent container, next to the left side of the parent container. But we can’t get it back to the first line, so setpadding-right: 1.5em;Make the space it actually occupies bigger than the first line can hold it, and it will return to the original card:beforeIt’s just the padding value that moves it to the left

OK, I’ve explained. Can I understand it? It depends on your creation.

It’s worth noting that the comment about width in the code above says “because margin is set below, there is no requirement for the width value size here”. Previously, it was required to be less than or equal to:beforeWidth, but now the negative value of margin left offsets the width of itself, so this requirement translates topadding-rightNow it’s equal to

Summary

So far, all the problems have been solved. For all the problems discussed above, the code is summarized as follows (the specific optimization is explained with notes):

CSS Style

.wrap {
    /*Height setting required*/
    height: 100px;
    /*It is used to set how many lines can be omitted. The value is generally the height value / line number of wrap, but the number of lines will be limited by the font size*/
    /*The font is too large, and many lines in the setting display will be ugly. They are all crowded together, so the actual value depends on the specific needs and practice*/
    line-height: 25px;
    /*With this attribute, the display effect is better, even if not supported by some browsers*/
    text-align: justify;
    overflow: hidden;
}

.wrap:before {
    float: left;
    /*This value can be set at will, no matter the unit or what*/
    width: 1em;
    height: 100%;
    content: '';
}

.wrap:after {
    float: right;
    /*The size is optional. It is best to set the EM unit. It can adapt to the font size*/
    /*If you want to use the following gradient effect, the effect will be better if the value is greater than the width value in before*/
	/*The larger the value, the more obvious the effect of the gradient is, the greater the range of influence. * /
    width: 2.5em;
    /*Same as the actual PX value of the row height of the parent element wrap*/
    height: 25px;
    /*This value should be the same as its own width, taking a negative value*/
    margin-left: -2.5em;
    /*This value should be the same as before width*/
    padding-right: 1em;
    content: '...';
    text-align: right;
    /*Here we start to use the float layout to locate and move*/
    position: relative;
    /*Take a negative value as the row height actual value of the parent element wrap*/
    top: -25px;
    left: 100%;
    /*The gradient effect is set to make the ellipsis and content connect naturally. It's not so abrupt. Pay attention to the color matching with the background where the text is located (replace white with background color)*/
    background: #fff;
    background: -webkit-gradient(linear, left top, right top, from(rgba(255, 255, 255, 0)), to(white), color-stop(50%, white));
    background: -moz-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
    background: -o-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
    background: -ms-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
    background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
}

.wrap .text {
    float: right;
    /*The value should be equal to the width value of wrap:before*/
    margin-left: -1em;
    width: 100%;
}

HTML file:

<div class="wrap">
    <span class="text">
        Example 2: mobile phone development
    </span>
</div>

Effect:

Advantage

  • The compatibility is good. It is satisfied that not all browsers of WebKit kernel can support it
  • Adaptive width

shortcoming

  • Fixed height, not adaptive height, so how many lines to display is also limited by font size
  • You need to wrap a label around the text to style it
  • From the point of view of reading style code, it is not well understood
  • If the element where the ellipsis is located does not use a gradient background, it will occasionally be truncated abruptly. If you want to use a gradient background, pay attention to the color matching under the background where the text is located

summary
 

In fact, I didn’t say which scheme is better. Only if it’s not suitable for you, I’ll ask you to peel a fruit and take a fruit knife. There’s no need to use a big knife. So, there is always one of the three solutions that meets your needs.

The above is the whole content of this article. I hope it will help you in your study, and I hope you can support developepaer more.

Recommended Today

IOS event handling, it’s enough for me~

This article belongs to the original of “Jianshu Liu Xiaozhuang”. Please indicate: < Jianshu Liu Xiaozhuang > https://www.jianshu.com/p/b0884faae603 I haven’t written blog for a long time. It’s just a year before and after. During this period, the blog has not been unchanged. Careful students should be able to find that I have been replying to […]