Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limit total maximum lines in two divs

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.

like image 301
Can Poyrazoğlu Avatar asked Jun 09 '21 14:06

Can Poyrazoğlu


People also ask

How do I limit the number of lines in CSS?

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.

How do I limit text in CSS?

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.

How do I use ellipsis text in CSS?

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.


3 Answers

With some flexbox, max-height, and a trick to place ellipsis, you could achieve this with pure CSS.

Screenshot:

Screenshot from code

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>
like image 109
Felipe Saldanha Avatar answered Oct 11 '22 23:10

Felipe Saldanha


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>
like image 2
sol Avatar answered Oct 12 '22 00:10

sol


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>
like image 2
norcal johnny Avatar answered Oct 12 '22 00:10

norcal johnny