0

What I need to implement is a text overflow effect, but instead of a "..." truncate which you would get by using text-overflow: ellipsis it should be a fade out on the last character. The element that should have this is a block of text, something like:

enter image description here

Multiple lines are allowed, if the text has no whitespaces and can't fit in one row, then break-word will be applied. A maximum of 5 lines are allowed so the fade should occur on the last character when the text can't fit considering the given max-height. Currently I have the following:

span {
  overflow: hidden;
  text-align: center;
  word-break: break-word;
  max-width: 72px;
  max-height: 75px; // line height * 5
}

I tried using

-webkit-mask-image: linear-gradient(130deg, #000 80%, transparent);

to achieve an effect which is similar, but this one fades out too many characters.

Is there a way to do this using only CSS?

Red
  • 35
  • 7
  • when do you want the effect to occure ? If there can be multiple lines, then no ellipse should occure... Do you always want the last letter to have a fade effect ? – Random Jan 04 '23 at 16:29
  • A maximum of 5 lines are allowed, so if the text would not fit in that given height that's when the "truncation" should occur on the final character, so at the bottom right corner of the `span` element. In the code example that's what the max-height rule is for, I forgot to clarify that. I'll edit. – Red Jan 04 '23 at 16:33
  • Any script trying to detect what is the pixel length of a string is not fully accurate. So you can't really know the x position of the last visible character. What you can do in JS is limiting to a number of characters, and if so, remove the remaining characters, and put the last character in a span, with a fade effect. But the prefered solution is simply not trying to fade :) – Random Jan 04 '23 at 16:46

2 Answers2

0

In this a bit old SO you has a directive to show more/less

I imagine you can to have a .css

.note-field:not(.show)::after{
  content:'';
  width:1rem;
  height: 1rem;;
  padding-left:.5rem;
  background-image: linear-gradient(to right, rgba(255,255,255,0), rgba(255,255,255,1));
  position: absolute;
  right:0;
  bottom:0;
}
Eliseo
  • 50,109
  • 4
  • 29
  • 67
0

So the issue was not solved in a CSS only way. As I don't want want to always have the fade-out effect at the last character in the text block, but only when the maximum line height is reached (75px is the max, each line is 15px high). I'm checking on the height of the span element using @ViewChild and I set the fade-out CSS class using Renderer2.

SCSS:

  span {
    overflow: hidden;
    text-align: center;
    word-break: break-word;
    max-width: 72px;
    max-height: 75px; // line height * 5
    position: relative;
 }
  
  .fade-out-text {
   ::after {
    content: "";
    position: absolute;
    right: 0;
    bottom: 0;
    width: 12px;
    height: 12px;
    background: linear-gradient(to left, white, transparent);
 }
}

Angular:

HTML

<span #ref>{{ text }}</span>

TS:

export class MyComponent implements AfterViewInit {
  @ViewChild('ref') ref: ElementRef;

  constructor(private readonly renderer: Renderer2) {}

  ngAfterViewInit(): void {
    // 60 is max line height - line height
    if (this.ref.nativeElement.offsetHeight > 60) {
      this.renderer.addClass(this.ref.nativeElement, 'fade-out-text');
    }
  }
}

Red
  • 35
  • 7