Please do not reprint without permission

preface

This is an old requirement, but there are still a lot of people looking for solutions online, especially the ones at the top of the search results, which only introduce incompatible solutions using -Webkit-line-clamp.

If you’re reading this, you’re probably looking for a better solution from all the same articles. That congratulations you, there is no better, only more suitable, of course, the premise is my article flow enough, can be top up you just have the opportunity to see.

Here are three methods of multi-line text truncation. Of course, the first method is the webkit-line-clamp scheme that you want to spit out. If you don’t want to see it, you can jump directly to the second method.

Use – its – line – clamp

Apply the following style to a container with multiple lines of text

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

Other properties are fixed except -webkit-line-clamp, which mainly displays objects as elastic telescopic box models and sets the arrangement of child elements of telescopic box objects.

The -webkit-line-clamp is used to control how many lines are omitted

Advantages:

  • Browser native support for ellipsis behavior, style looks comfortable
  • Simple and easy to use

Disadvantages:

  • If you look at the prefix of the property, this iswebkitKernel browser support, compatibility is not extensive.

Usage scenarios

This is best if you only work with webKit kernel browsers or mobile browsers (which are mostly WebKit kernel browsers).


Make use of absolute positioning

This is pretty straightforward. First we reserve a space to the right of the container for ellipses. Use the padding-right: 1em; An ellipsis is approximately 1em, and the em unit is used in response to the font size.

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

html

<div class="wrap">content</div>
Copy the code

css

.wrap3 {
    position: relative;
    padding-right: 1em;
    /*max-height is a multiple of line-height */
    max-height: 3.6 em;
    line-height: 1.2 em;
    text-align: justify;
    overflow: hidden;
}

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

Effect (multi-content) :

In that case, the ellipsis will always be there. So to solve this problem, we cover the ellipsis with a square that’s the same color as the background, and the key is, how do you know when to cover it up and when not to cover it up?

The box used to block the ellipsis is also absolutely positioned, and is set to the right, right: 0, but the bottom value is not set. If not set, the box will follow the actual height of the text, not the max-height. This way, when no ellipsis is needed (i.e., no more than max-height), the bottom: 0 situation will block the ellipsis. When ellipses are omitted (i.e., exceeding max-height), they will not be blocked and will themselves be hidden by overflow: hidden.

So the final solution is:

html

<div class="wrap">content</div>
Copy the code

css

.wrap {
    position: relative;
    /*line height = 0 */
    line-height: 1.2 em;
    max-height: 3.6 em;
    /* The padding-right property is set to a negative value of the padding-right property */
    /*margin-left: -1em; * /
    /* The ellipsis takes up about 1em */
    padding-right: 1em;
    text-align: justify;
    overflow: hidden;
}

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

.wrap:after {
    position: absolute;
    right: 0;
    /* The width and height should be 1em, because the ellipsis takes up about 1em of space and is used to cover the ellipsis
    width: 1em;
    /* Same as the actual line height of wrap */
    height: 1.2 em;
    content: ' ';
    /* The ellipsis must be the same color as the background */
    background-color: #fff;
}
Copy the code

Effect:

The demo address

advantages

  1. Good compatibility, major browsers support
  2. Adaptive height, no need to write height, set more than how many lines need to be omitted display
  3. Adaptive width
  4. Adaptive font size, which does not affect the original requirement to omit as many lines as required

disadvantages

  1. The right side of the text is deliberately left empty for the ellipsis
  2. You need to consider the background color, because the after pseudo-class uses the background color to hide the ellipsis

Use float layouts

This program is not solid for the basic knowledge of children’s shoes, may not be very good to understand, if only want to find a solution do not want to know the principle, you can go directly to the summary

Before we talk about the solution, we need to understand this phenomenon:

So here’s a piece of HTML

<div class="wrap">
    <div class="left">Left floating</div>
    <div class="right1">Right Floating 1 Right Floating 1 Right Floating 1 Right Floating 1 Right Floating 1 Right Floating 1 Right Floating 1 Right Floating 1 Right Floating 1 Right Floating 1 Right Floating 1 Right Floating 1 Right Floating 1 Right Floating 1 Right Floating 1 Right Floating 1 Right Floating 1 Right Floating 1 Right Floating 1 Right Floating 1 Right Floating 1</div>
    <div class="right2">Right float 2</div>
</div>
Copy the code

Apply a style like this

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

It would normally look like this, and this is what you would expect:

This normal phenomenon occurs under the following conditions:

  1. .right1The height does not exceed.leftHeight (i.e. less content)
  2. .right2The width is less than.right1The width of the

Okay, so you get the picture. So what happens next is that we increase the content of.right1 beyond the height of the left float

Why am I doing this? Er… I don’t know the basics of float. I don’t know the basics of float. I just know this is a normal representation of float.

The conditions for this phenomenon are:

  1. .right1More than.leftThe height of (i.e., content)
  2. .right2The width is less than or equal to.leftThe width of the

Knowledge is translated into requirements realization

Now that we understand these two scenarios, how can we use this knowledge to match the requirements?

Let’s say the text content of float 1 right is what we want to omit multiple lines, float 2 right is the ellipsis (…). . In this way, the ellipsis is the first case when there is little content, and the ellipsis is the second case when there is much content.

This kind of dynamic change, is not like “text is not omitted, text is omitted” this kind of demand change. On this basis, we need to solve the problem that in the first case, the right float 2 is hidden, and in the second case, the right float 2 appears in the bottom right corner of the.wrap, and the content beyond the height is hidden.

To solve these problems, just use position: relative; Relative positioning can be. .wrap Parent container application overflow: hidden; . In the first case, it is positioned outside the parent container and hidden. In the second case, the parent container is positioned in the lower right corner.

Well, now the focus of the solution is on the problem of precise positioning (the next section). Before dealing with the positioning problem, first translate the current situation into the actual requirements code:

<! Float left and float right 2 replace actual tags with pseudo-class elements -->
<div class="wrap">
    <div class="text">Floating right 1</div>
</div>
Copy the code
.wrap {
    height: 100px;
    /*line-height controls how many lines of text to display */
    line-height: 20px;
    overflow: hidden;
}
.wrap:before {
    float: left;
    /* must be greater than or equal to the width of the after element */
    width: 1.5 em;
    height: 100%;
    content: ' ';
}
.text {
    float: right;
    /* Use negative marginLeft to avoid whitespace generated by before */
    /* You can't have a blank left side of your parent container */
    margin-left: -1.5 em;
    /* Now that negative marginLeft is used, the text container will fill up 100% of the parent container */
    width: 100%;
}
.wrap:after {
    float: right;
    /* Generally three dots are about 1em wide, using em as a unit to adjust font size */
    width: 1em;
    content: '... ';
}
Copy the code

If you’re wondering why. Text is set to width: 100%; Will it get stuck under :before? Because even if. Text is set to margin-left: -1.5em; “, but actually does not affect the original document flow, the original is what it should be, set negative margin, only affect the. Text itself rendering style.

How to position

The solution to the positioning problem is based on the code in the previous section. The current problems are as follows:

  1. The ellipsis appears when the content is too small to omit
  2. The ellipsis is hidden when it needs to be omitted

Let’s deal with the second problem

To move the :after to the right of the.wrap, move it up to the last line.

In position: relative; Wrap line height is the same as the actual value of the wrap line height. The key is the left value, how to get it right in the bottom right corner.

If you know the width of the. Text text (e.g. 100px), set it left: 100px; Can, but this can only be for the fixed width of the case, not adaptive width. To be adaptive, the left value is a percentage, so what percentage is it? It’s tangled. So let’s just take 100%, and you’ll see that it’s going to move out of the parent container.

So if that happens to be in the bottom right corner, the initial position of the ellipsis has to be to the left of the wrap, right next to the wrap, so that it’s 100% left in the bottom right corner.

The problem now becomes how to make :after appear just to the left of the.wrap. The following code may be a bit confusing to the uninitiated (the additions are in the comments) :

.wrap:after {
    float: right;
    /* The width is not required */ because margin is set below
    width: 1em;
    content: '... ';
    
    /* These two properties are set next to each other
    /* This value should be the same as its width, take a negative */
    margin-left: -1em;
    /* This value should be the same width as before */
    padding-right: 1.5 em;
    
    /* This is where the ellipsis is located */
    position: relative;
    left: 100%;
    /* Is the same as the actual height of the parent element wrap, with a negative value */
    top: -20px;
}
Copy the code

About setting margin and padding values, if you can understand it, it’s better. If not, I’ll try to explain it, but it’s really hard to say.

Margin-left: -1em; The width of :after is smaller than that of :before, so it would be in a line as float

Margin-left: -1em; margin-left: -1em; After, :after returns to the first line of the parent container, immediately to the left. But we can’t make it go back to the first line, so padding-right: 1.5em; Make it take up too much space in the first row, so it goes back to where it used to be under :before, but the padding makes it move to the left

Ok I explained, can understand, can only depend on your fate ha ha.

It is worth noting that the comment about width in the above code says “since margin is set below, there is no requirement for the width value here”. Before, it requires the width to be less than or equal to :before, but now because the width is offset by the negative value of margin-left. So this requires converting to padding-right, which is equal to

summary

So far, all the problems have been solved. For all the issues discussed above, the following code can be summarized (specific optimizations are commented) :

CSS styles

.wrap {
    /* Requires a fixed height */
    height: 100px;
    /* Sets how many lines to display before omission. The value is usually the wrap height/line number, but this line number is limited by the font size */
    /* The font size is too large, and the Settings for many lines will be ugly, so the actual value depends on requirements and practice */
    line-height: 25px;
    /* Add this attribute to display better, even if some browsers do not support */
    text-align: justify;
    overflow: hidden;
}

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

.wrap:after {
    float: right;
    /* The size is arbitrary, the EM unit is best, and can be adjusted with font size */
    /* If you want to use the gradient below, it will be better if the value is larger than the width value in before */
	/* The larger the value, the more obvious the effect of the gradient is. * /
    width: 2.5 em;
    /* The line height of the parent element wrap is the same as the actual px value */
    height: 25px;
    /* This value should be the same as its width, take a negative */
    margin-left: -2.5 em;
    /* This value should be the same width as before */
    padding-right: 1em;
    content: '... ';
    text-align: right;
    /* Here we begin to move using positioning based on the float layout */
    position: relative;
    /* Is the same as the actual height of the parent element wrap, with a negative value */
    top: -25px;
    left: 100%;
    /* The gradient effect is set so that the ellipsis and the content are natural and not abrupt, be careful to match the color of the text background (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;
    /* This value should be equal to wrap:before width */
    margin-left: -1em;
    width: 100%;
}
Copy the code

HTML file:

<div class="wrap">
    <span class="text"</span> </div>Copy the code

Effect:

The demo address

advantages

  1. Good compatibility, meet not webKit kernel browsers can support
  2. Adaptive width

disadvantages

  1. Fixed height, cannot be adjusted height, so the number of lines displayed is limited by the font size
  2. You need to wrap a label around the text to set the style
  3. It’s not easy to understand from the point of view of reading the style code
  4. If the ellipsis element does not have a gradient background, it will occasionally be abruptly truncated. If a gradient background is used, be careful to match the color of the text in the background

conclusion

In fact, there is no saying which plan is better, only suitable for your plan, ask you to peel a fruit, take a fruit knife, there is no need to use a large knife. So, of the three solutions, there is always one that meets your needs.

Please do not reprint without permission