How to omit multiple lines with CSS

Preface

This is an old requirement, but there are still many people looking for solutions online, especially those ranked high in search results, which only introduce solutions using -webkit-line-clamp that have poor compatibility.

If you see this article, it may mean that you jumped from so many stereotyped articles and want to find a better solution. Congratulations, there is no better one, only one that is more suitable or inappropriate. Of course, the premise is that my article has enough traffic and can be promoted so that you have a chance to see it.

Here are three ways to truncate multi-line text. Of course, the first one is the webkit-line-clamp solution that makes you want to vomit when you see it. If you don’t want to see it, just skip to the second method and start reading.

Use -webkit-line-clamp

Apply the following style to the container of multi-line text

div {

display: -webkit-box;

-webkit-box-orient: vertical;

overflow: hidden;

-webkit-line-clamp: 2;

}

Except for -webkit-line-clamp, other properties are fixed. They mainly display the object as a flexible box model and set the arrangement of the child elements of the flexible box object.

And -webkit-line-clamp is used to control how many lines to omit

advantage:

The omission behavior supported by the browser natively makes the style look very comfortable.

Simple and convenient to use

shortcoming:

You can tell by looking at the prefix of the attribute that this is supported by webkit-based browsers, and the compatibility is not extensive.

scenes to be used

If you only target webkit core browsers or mobile terminals (most mobile browsers are webkit core), then using this solution is the best.

Use absolute positioning

This solution is actually easy to understand. First, we reserve a space on the right side of a container containing content for an ellipsis. Use padding-right:1em; to reserve space. Why is it 1em? An ellipsis is almost 1em. , using em units is to respond to the font size.

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

html

<div class="wrap">内容</div>

css

.wrap3 {

position: relative;

padding-right: 1em;

/*max-height is several times of line-height, and it can be as many times as many lines as you want to display*/

max-height: 3.6em;

line-height: 1.2em;

text-align: justify;

overflow: hidden;

}

.wrap3:before {

position: absolute;

right: 0;

bottom: 0;

content: "...";

}

Effect (when there is multiple content):

In this case, the ellipsis will always exist. So to solve this problem, we use a square with the same color as the background to cover the ellipses. The key point is, how do we know when to cover it and when not to cover it?

Idea: The box used to block the ellipsis is also absolutely positioned, and is set to the right, right:0, but the bottom value does not need to be set. If not set, the box will move with the actual height of the text content, not max-height. the height of. In this case, when there is no need to omit (that is, it does not exceed max-height), it will be the case of bottom:0, and the ellipsis will be blocked. When omission is to be made (that is, exceeding max-height), the ellipsis cannot be blocked, and it itself will be hidden by overflow:hidden.

So the final solution is:

html

<div class="wrap">内容</div>

css

.wrap {

position: relative;

/*line-height and height must cooperate with each other. Omit as many lines as are displayed, which is the multiple of line-height*/

line-height: 1.2em;

max-height: 3.6em;

/*This attribute depends on the requirements to determine whether to set it. Because padding-right is set, more space is freed up. This value is generally the negative value of padding-right*/

/*margin-left: -1em;*/

/*Just write this value to 1em, because the ellipsis probably takes up 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;

/* Just write the width and height to 1em, because the ellipsis takes up about 1em of space and is used to cover the ellipsis, which is basically the same as wrap's padding-right*/

width: 1em;

/*Consistent with the actual value of wrap’s row height*/

height: 1.2em;

content: "";

/*The color must be the same as the background color so that the ellipsis can be covered and there will be no difference*/

background-color: #fff;

}

Effect:

demo address

advantage

Good compatibility, supported by major browsers

Adaptive height, no need to hard-code the height, set the number of rows before they need to be omitted.

adaptive width

Adaptive font size, the font size will not affect the original requirements, that is, as many lines as required can be omitted.

shortcoming

There will be intentionally left some space on the right side of the text for ellipses to be placed.

You need to consider the background color because the after pseudo-class uses the background color to cover the ellipses.

Use float layout

This solution may not be easy to understand for children who do not have solid basic knowledge. If you just want to find a solution and don’t want to know the principles, you can go directly to the summary.

Before talking about this plan, we must first understand this phenomenon:

There is such 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 Float right 1 Float right 1</div>

<div class="right2">Float right 2</div>

</div>

Apply this style

.wrap {

height: 100px;

}

.left {

float: left;

width: 60px;

height: 100%;

background: pink;

}

.right1 {

float: right;

/*Occupy the remaining width of wrap except left*/

width: calc(100% - 60px);

background: #95d9f8;

}

.right2 {

float: right;

background: yellow;

}

Under normal circumstances, it will be displayed like this, which is also what everyone can generally imagine and expect:

The conditions for this normal phenomenon to occur are:

The height of .right1 does not exceed the height of .left (that is, there is less content)

The width of .right2 is less than the width of .right1

Okay, everyone understands this situation. Then next, we increase the content of .right1 to exceed the height of the left float, and the next scene will happen.

The right floating 2 is stuck in the lower left corner.

You want to ask me why this is happening? Um... It seems that your basic knowledge of float is not solid. I suggest you consolidate your basic knowledge. In fact, I can't explain it. I only know that this is a normal behavior of float.

The conditions for this phenomenon to occur are:

The height of .right1 exceeds the height of .left (that is, there is more content)

The width of .right2 is less than or equal to the width of .left

Transform knowledge into needs realization

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

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

Is this dynamic change a change in demand like "don't omit when the text is small, and omit when there is a lot of text"? On this basis, what we need to solve is that in the first case, the right floating 2 is hidden. In the second case, the right floating 2 appears in the lower right corner of .wrap, and the content that exceeds the height is hidden.

To solve the above problem, just use position:relative; for relative positioning. .wrap the parent container to apply overflow:hidden;. In the first case, if it is positioned outside the parent container, it will be hidden. In the second case, locate the lower right corner of the parent container.

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

<!--Replace the actual labels with left floating and right floating 2 pseudo-class elements -->

<div class="wrap">

<div class="text">Float right 1</div>

</div>

.wrap {

height: 100px;

/*line-height is used to control the maximum number of lines of text displayed*/

line-height: 20px;

overflow: hidden;

}

.wrap:before {

float: left;

/*Be greater than or equal to the width of the after element*/

width: 1.5em;

height: 100%;

content: "";

}

.text {

float: right;

/*Use a negative marginLeft to avoid the blank space generated by before*/

/*Because of actual requirements, it is impossible for your parent container to have a blank space on the left side*/

margin-left: -1.5em;

/*Since the negative value marginLeft is used, the width of the text container can occupy 100% of the width of the parent container*/

width: 100%;

}

.wrap:after {

float: right;

/*Generally three dots are almost 1em wide, using em as the unit can adapt the font size*/

width: 1em;

content: "...";

}

If you are curious at this time, why is .text set with width:100%;, but when there is a lot of content: after is still stuck under: before? This is because even if margin-left:-1.5em; is set for .text, it will not actually affect the original document flow. It is what it should be. Setting a negative margin will only affect .text The presentation style of itself.

How to position

Solving the positioning problem is based on the code in the previous section. The issues currently exposed include:

When the content is small and there is no need to omit, the ellipses are displayed.

When there is a lot of content and needs to be omitted, the ellipses are hidden.

Let’s solve the second problem first

Idea: Move this:after to the right to the right of .wrap, and move it up to the last line.

If you use position:relative; to control it, the top value is easy to select. It is the same as the actual value of line-height of .wrap. Just take a negative value. The key is the left value, how to get it so that it can be displayed in the lower right corner.

If you can clearly know the width of .text (such as 100px), you can actually set left:100px;, but this can only be used for fixed width situations and cannot adapt to the width. To achieve self-adaptation, just take the value of left as a percentage. So what percentage is it? This is tangled. Simply take 100%, and you will find that it will be moved out of the parent container.

If it wants to appear exactly in the lower right corner, the initial position of the ellipsis must be on the left side of .wrap, next to .wrap, so that it can appear in the lower right corner after left:100%.

Now the question becomes how to make :after appear just on the left side of .wrap. The following code may be a little difficult to understand for people who don’t have a solid foundation (the new part is in the comments):

.wrap:after {

float: right;

/*Because margin is set below, there is no requirement for the width value here*/

width: 1em;

content: "...";

/*These two properties are set immediately to the left of .wrap*/

/*This value should be the same as its own width, take a negative value*/

margin-left: -1em;

/*This value must be the same as the before width*/

padding-right: 1.5em;

/*This is the location of the ellipses*/

position: relative;

left: 100%;

/*The same as the actual row height value of the parent element wrap, take a negative value*/

top: -20px;

}

Regarding setting the margin and padding values, it would be best if you can understand it. If not, I will try my best to explain it. In fact, it is really difficult to explain.

First, when applying margin-left:-1em;, since the width of :after is smaller than that of :before, according to the original float layout, in one line

Pink is left floating, blue and red are right floating. If the width of red continues to increase to the remaining space except pink, because there is not enough space in one line, blue will be squeezed into a new line and floated right. But if you set the blue margin-left to a negative value of its own width, then there is still room for it in the row of space, and it becomes like this:

According to the above principle, after setting margin-left:-1em;, :after will return to the first line of the parent container, next to the left side of the parent container. But we can't let it go back to the first line, so we set padding-right: 1.5em; so that the actual space it occupies becomes larger than the first line can accommodate it, and it returns to the original one stuck under: before position, just the padding value makes it move to the left

Okay, I’ve finished explaining it. Whether you understand it or not depends on your luck, haha.

It is worth noting that the comment about width in the above code reads "Because margin is set below, there is no requirement for the width value here." Previously, it was required to be less than or equal to: before width, but now due to the use of margin-left negative value offset has its own width, so this requirement is converted to padding-right, which is equal to

summary

Up to now, all problems have been solved. All the issues discussed above are summarized in the following code (specific optimizations are explained in comments):

css style

.wrap {

/*Need to set height*/

height: 100px;

/*Used to set how many lines to display before they are omitted. The value is generally obtained by the height value of wrap/the number of lines, but this number of lines will be limited by the font size*/

/*The font is too big, and it will look ugly if you set it to display many lines, all crowded together, so the actual value depends on the specific needs and practice*/

line-height: 25px;

/*Add this attribute for better display effect, even if some browsers do not support it, it will not have much impact*/

text-align: justify;

overflow: hidden;

}

.wrap:before {

float: left;

/*This value can be set arbitrarily, regardless of the unit*/

width: 1em;

height: 100%;

content: "";

}

.wrap:after {

float: right;

/*The size is arbitrary, it is best to set the em unit, which can be adaptive as the font size changes*/

/*If you want to use the following gradient effect, then the effect will be better if this value is greater than the width value in before*/

/*The larger the value, the more obvious the effect of the gradient and the wider the range of influence. */

width: 2.5em;

/*The same as the actual px value of the parent element wrap line height*/

height: 25px;

/*This value should be the same as its own width, take a negative value*/

margin-left: -2.5em;

/*This value must be the same as the before width*/

padding-right: 1em;

content: "...";

text-align: right;

/*Here we start to use positioning and movement based on float layout*/

position: relative;

/*The same as the actual row height value of the parent element wrap, take a negative value*/

top: -25px;

left: 100%;

/*The gradient effect is set to make the connection between the ellipsis and the content more natural and less abrupt. Pay attention to match the color of the background where the text is located (replace white with the 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 must be equal to the width value of wrap:before*/

margin-left: -1em;

width: 100%;

}

html file:

<div class="wrap">

<span class="text">

Example 2: Distributing equipment to solve mobile phone development issues

</span>

</div>

Effect:

demo address

advantage

It has good compatibility and can be supported by browsers that are not webkit-based.

adaptive width

shortcoming

Fixed height, cannot adapt to the height, so the number of lines displayed is also limited by the font size

You need to wrap the text with a label to set the style

From the perspective of reading the style code, it is not easy to understand.

If the element where the ellipsis is located does not use a gradient background, it will occasionally be cut off abruptly. If you want to use a gradient background, pay attention to the color matching with the background where the text is located.

Summarize

In fact, there is no saying which solution is better, only the solution that suits you or not. Just ask you to peel a fruit and use a fruit knife. There is no need to use a big knife. Therefore, among the three options, there is always one that meets your needs.

————————————————

Source: https://www.weidianyuedu.com

Guess you like

Origin blog.csdn.net/hdxx2022/article/details/129319349