I know how to make a single div to put ellipsis after n number of lines using (where n is 2 lines in this case):
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
It works one one div
but I have a different problem. I have a title and a description of some content, and I want to limit both fields to 3 lines at max by themselves, but also a total of 5 lines (instead of the maximum possible, 6 in that case) in total. In other words, I'd like to cut description after two lines (with an ellipsis) if the title is 3 lines.
How do I achieve this (preferably with no or smallest amount of Javascript)? I only need to support (mobile) Safari for now.
There are a few ways to do it with pure CSS. Let's learn how to achieve that. The easiest way to limit text to n lines is to use line-clamp . N can be any positive number, but it will be two or three lines most of the time.
If you want to limit the text length to one line, you can clip the line, display an ellipsis or a custom string. All these can be done with the CSS text-overflow property, which determines how the overflowed content must be signalled to the user.
To clip at the transition between characters you can specify text-overflow as an empty string, if that is supported in your target browsers: text-overflow: ''; . This keyword value will display an ellipsis ( '…' , U+2026 HORIZONTAL ELLIPSIS ) to represent clipped text.
With some flexbox, max-height
, and a trick to place ellipsis, you could achieve this with pure CSS.
Screenshot:
See it at Codepen.
:root {
--field-max-lines: 3;
--desc-max-lines: 2; /* if title reached maximum number of lines */
--title-lh: 30px;
--desc-lh: 20px;
font-size: 16px;
}
* {
margin: 0;
padding: 0;
}
body {
display: flex;
gap: 20px;
padding: 20px;
}
div {
display: flex;
flex-direction: column;
max-height: calc(var(--field-max-lines) * var(--title-lh) + var(--desc-max-lines) * var(--desc-lh));
width: 200px;
}
div>* {
overflow: hidden;
position: relative;
padding-right: 1rem;
}
div>*::before {
position: absolute;
content: "...";
bottom: 0;
right: 0;
}
div>*::after {
position: absolute;
content: "";
right: 0;
width: 1rem;
height: 1.5rem;
}
strong {
flex: none;
line-height: var(--title-lh);
max-height: calc(var(--field-max-lines) * var(--title-lh));
font-size: 20px;
}
strong,
strong::after {
background: red;
}
p {
line-height: var(--desc-lh);
max-height: calc(var(--field-max-lines) * var(--desc-lh));
}
p,
p::after {
background: yellow;
}
<div>
<strong>This title has 2 lines. This title has 2 lines.</strong>
<p>This description has 4 lines. This description has 4 lines. This description has 4 lines. This description has 4 lines.</p>
</div>
<div>
<strong>This title has 3 lines. This title has 3 lines. This title has 3 lines.</strong>
<p>This description has 2 lines. This description has 2 lines.</p>
</div>
<div>
<strong>This title has 3 lines. This title has 3 lines. This title has 3 lines.</strong>
<p>This description has 3 lines. This description has 3 lines. This description has 3 lines.</p>
</div>
<div>
<strong>This title has 4 lines. This title has 4 lines. This title has 4 lines. This title has 4 lines. This title has 4 lines.</strong>
<p>This description has 3 lines. This description has 3 lines. This description has 3 lines.</p>
</div>
getClientRects can return the line length for an inline element.
const { length } = document.querySelector("h1 span").getClientRects();
length >= 3 && document.querySelector("p").style.setProperty("--line-clamp", 2);
div > * {
--line-clamp: 3;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: var(--line-clamp);
-webkit-box-orient: vertical;
}
<div>
<h1><span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Natus repellendus ducimus minus met consectetur</span></h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Animi consectetur quo, perspiciatis, pariatur, deleniti enim molestiae sunt debitis aut nam iure cumque sint aperiam est! Vel temporibus atque excepturi sed!</p>
</div>
How about comparing the clientHeight of each text area and use a simple. conditional statement like this..
var title = document.querySelector(".box h3"),
des = document.querySelector(".box p");
console.log("titleHeight = " + title.clientHeight + "px");
console.log("descriptionHeight = " + des.clientHeight + "px");
if (title.clientHeight > 90 && des.clientHeight > 90){
title.style.webkitLineClamp = 3;
des.style.webkitLineClamp = 2;
}else{
title.style.webkitLineClamp = 3;
des.style.webkitLineClamp = 3;
}
.box h3 {
display: -webkit-box;
-webkit-line-clamp: inherit;
-webkit-box-orient: vertical;
overflow: hidden;
}
.box p {
display: -webkit-box;
-webkit-line-clamp: inherit;
-webkit-box-orient: vertical;
overflow: hidden;
}
.box h3 {
line-height: 30px;
}
.box p {
line-height: 30px;
}
<div class="box">
<h3>Hey, don't cut me off like that. I want to speak my mind and don't appreciate being put into a box. Hey, don't cut me off like that. I want to speak my mind and don't appreciate being put into a box.</h3>
<p>Hey, don't cut me off like that. I want to speak my mind and don't appreciate being put into a box. Hey, don't cut me off like that. I want to speak my mind and don't appreciate being put into a box.</p>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With