6

I have a box with text. It shows only 2 lines by default and shows the whole text when the user hovers over it. However, I have a problem animating it. The display property seems to be not animatable.

How can I animate it?
If it helps, I'm also using "framer-motion" and it's okay if you have a workaround using it.

.box {
  transition: all 0.3s ease-in-out; /* doesn't work */
}

.title {
  color: green;
  font-weight: bold;
}

.text {
   display: -webkit-box;
   -webkit-line-clamp: 2;
   -webkit-box-orient: vertical;  
   overflow: hidden;
   
   transition: all 0.3s ease-in-out; /* doesn't work */
}

.box:hover .text {
   display: block;
}
<div class="box">
  <span class="title">Title</span>
  <div class="text">
  Et eirmod erat diam ipsum sit diam ut et est at ut tempor consequat nisl duis ut justo sit. Aliquyam adipiscing et esse consetetur dolores et suscipit stet magna invidunt sea et sadipscing ea at magna labore. Molestie dolores justo consetetur consequat. Sed sit aliquyam eirmod amet nonummy facilisis diam. Diam lorem dolores stet labore eos duo illum facer qui justo duo stet consetetur diam magna.
  </div>
</div>

Why it's not a duplicate question:

I want to specifically use the line-clamp (or if there's a similar property) to limit the number of lines by the number I want. I don't want to use guesses or probability!

Shahriar
  • 1,855
  • 2
  • 21
  • 45

3 Answers3

1

As you can't animate line-clamp (or display) we have to find something animatable but which will nonetheless show exactly two lines in the non-hovered state.

max-height is animatable.

This snippet takes a 'guess' at a suitable max-height for when line-clamp is in use - it needs to be larger than 2 lines high so that the line-clamp can work but it needs to be not so large that there is too discernible a jump when we start the hover transform.

.box {
  transition: all 0.3s ease-in-out;
}

.title {
  color: green;
  font-weight: bold;
}

.text {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  transition: all 0.3s ease-in-out;
  /* ADDED */
  max-height: 3em;
}

.box:hover .text {
  -webkit-line-clamp: 40;
  max-height: 40em;
}
<div class="box">
  <span class="title">Title</span>
  <div class="text">
    Et eirmod erat diam ipsum sit diam ut et est at ut tempor consequat nisl duis ut justo sit. Aliquyam adipiscing et esse consetetur dolores et suscipit stet magna invidunt sea et sadipscing ea at magna labore. Molestie dolores justo consetetur consequat.
    Sed sit aliquyam eirmod amet nonummy facilisis diam. Diam lorem dolores stet labore eos duo illum facer qui justo duo stet consetetur diam magna.
  </div>
</div>

This is of course only a partial method as when hovering is stopped the transition back to line-clamp: 2 is not smooth. I can't at the moment see a way around that other than to invoke JS on animationend and put the line clamp back at that point.

A Haworth
  • 30,908
  • 4
  • 11
  • 14
  • That's the closest thing to what I'm looking for! But I think `max-height` has no effect here; the `line-clamp` seems to be animatable on its own. The only problem is not being smooth... – Shahriar Feb 12 '22 at 10:24
  • The max-height is essential as it is the animatable property. Set the time to several seconds so you can see the text expanding gradually. Then take the max-width settings out and try again - the text expands instantly. – A Haworth Feb 12 '22 at 11:08
  • Oh... I see. However, not so noticeable since neither of them is smooth. – Shahriar Feb 12 '22 at 11:12
  • Without the max-height it is instant, with the max-height it is gradual. Not sure what you want to happen with lines of text - do you want a character to appear gradually top to bottom? (as opposed to the text appearing a line at a time?). – A Haworth Feb 12 '22 at 11:18
  • 1
    Wait. There's a difference between browsers. I'm using Firefox and the change is gradual (without `max-height`), but in Chrome it's instant. Firefox even animates the closing (returning to 2 lines). – Shahriar Feb 12 '22 at 11:59
  • Ah, good experiment! I was doing initial tests on Chrome/Edge on Windows10 and there the change is only gradual if you have the max-height. – A Haworth Feb 12 '22 at 12:13
0

Here is my solution newer solution which I guess help you achieve what you are looking for, Display property doesn't work with transition, you can use height.

let div1 = document.querySelector("#div1");
let height = div1.offsetHeight;
div1.classList.add('text');
div1.addEventListener("mouseover", () => {
  div1.style.height = height + "px";
});
div1.addEventListener("mouseout", () => {
  div1.style.height = "39px";
});
.text {
  overflow: hidden;
  height: 39px;
  transition: all 0.3s ease-in-out;
}

.text::after {
  content: "..";
  background-color: #fff;
  color: #000;
  z-index: 999;
  position: absolute;
  right: 20px;
  top: 28px;
  display: inline-block;
  width: 75px;
  transition: all 0.3s ease-in-out;
}

.text:hover::after {
  width: 0;
  visibility: hidden;
}
<div class="box">
  <div id="div1">
    Et eirmod erat diam ipsum sit diam ut et est at ut tempor consequat nisl duis ut justo sit. Aliquyam adipiscing et esse consetetur dolores et suscipit stet magna invidunt sea et sadipscing ea at magna labore. Molestie dolores justo consetetur consequat.
    Sed sit aliquyam eirmod amet nonummy facilisis diam. Diam lorem dolores stet labore eos duo illum facer qui justo duo stet consetetur diam magna. Et eirmod erat diam ipsum sit diam ut et est at ut tempor consequat nisl duis ut justo sit. Aliquyam
    adipiscing et esse consetetur dolores et suscipit stet magna invidunt sea et sadipscing ea at magna labore. Molestie dolores justo consetetur consequat. Sed sit aliquyam eirmod amet nonummy facilisis diam. Diam lorem dolores stet labore eos duo illum
    facer qui justo duo stet consetetur diam magna. Et eirmod erat diam ipsum sit diam ut et est at ut tempor consequat nisl duis ut justo sit. Aliquyam adipiscing et esse consetetur dolores et suscipit stet magna invidunt sea et sadipscing ea at magna
    labore. Molestie dolores justo consetetur consequat. Sed sit aliquyam eirmod amet nonummy facilisis diam. Diam lorem dolores stet labore eos duo illum facer qui justo duo stet consetetur diam magna. Et eirmod erat diam ipsum sit diam ut et est at
    ut tempor consequat nisl duis ut justo sit. Aliquyam adipiscing et esse consetetur dolores et suscipit stet magna invidunt sea et sadipscing ea at magna labore. Molestie dolores justo consetetur consequat. Sed sit aliquyam eirmod amet nonummy facilisis
    diam. Diam lorem dolores stet labore eos duo illum facer qui justo duo stet consetetur diam magna.
  </div>
</div>
Nexo
  • 2,125
  • 2
  • 10
  • 20
0

You can use opacity instead of display. and a span tag for a portion of text that you want:

.title {
  color: green;
  font-weight: bold;
}

.box {
  background: lightblue;
}


.show {
  opacity: 0;
  transition: opacity 1s ease-in-out;
}

.box:hover .show {
  opacity: 1;
}
<div class="box">
  <span class="title">Title</span>
  <div class="text">
    Et eirmod erat diam ipsum sit diam ut et est at ut tempor consequat nisl duis ut justo sit. Aliquyam adipiscing et esse consetetur dolores et
     <span class="show">
        suscipit stet magna invidunt sea et sadipscing ea at magna labore. Molestie dolores justo consetetur consequat. Sed sit aliquyam eirmod amet nonummy facilisis diam. Diam lorem dolores stet labore eos duo illum facer qui justo duo stet consetetur diam magna.
     </span>
  </div>
</div>
Shahriar
  • 1,855
  • 2
  • 21
  • 45
Arman Ebrahimi
  • 2,035
  • 2
  • 7
  • 20