3

I am trying to display a paragraph on the webpage, The paragraph will be updated based on user actions ( content on paragraph will change ) I need to limit the content to n number of lines. and if user try to add anything to the paragraph. It should add and truncate the beginning with an ellipse to indicate.

Example with max line 2 - Line number 1, Line2 After adding one more line (line3) , it should be - ...Line2. Line3. Tried the following ways

p {
display: -webkit-box;
max-width: 200px;
-webkit-line-clamp: 4;
-webkit-box-orient: vertical;
overflow: hidden;}

Can't position the ellipse on beginning of text and couldn't find a way to truncate from the beginning. it is limited to 4 lines

    .ellipsis {
    overflow: hidden;
    width: 60px;
    position: relative
    direction: rtl; 
    margin-left: 15px;
    white-space: nowrap;
}   
.ellipsis:after {
    position: absolute;
    left: 0px;
    content: "...";
}

since I am using multiline , can't use nowrap. There are different questions related in stackoverflow. But this seems to be different requirement.

Referred questions - I need an overflow to truncate from the left, with ellipses

Text-overflow ellipsis on left side

Applying an ellipsis to multiline text

Naveen
  • 356
  • 2
  • 10
  • [This](https://davidwalsh.name/css-ellipsis-left) may be helpful. – Gerard Dec 05 '22 at 09:05
  • Yeah , I tried this. Unfortunately I have multiple lines, and setting nowrap will limit to 1 line – Naveen Dec 05 '22 at 09:07
  • Try [this](https://youtu.be/b6iVByCOx8A) – Skin_phil Dec 05 '22 at 09:16
  • Already tried these, Were able to add ellipse at end of the paragraph. But couldn't add to beginning and also this won't trim from beginning – Naveen Dec 05 '22 at 09:21
  • @MacPicChu Does your multiline paragraph have any children elements within? For example `span` as a line? If so, you could then target all but the last two lines / `span`s with your CSS. – FiddlingAway Dec 10 '22 at 11:02
  • @FiddlingAway No, the paths are rendering in a single div with li elements . – Naveen Dec 10 '22 at 14:22
  • @MacPicChu Ah, I see. Do you have any control on how the paragraph is created and populated, and if you do, would it complicate things to introduce `spans` for lines? If this is not acceptable for any reason, I guess you could go down the Javascript route, as suggested in the answer by Trevor Dixon. – FiddlingAway Dec 12 '22 at 20:11

3 Answers3

4

I'd start with something like this.

function fit(el, text) {
  const outer = el.parentElement;
  const words = text.split(' ');
  let chop = 0;
  do {
    el.innerText = chop ? `… ${words.slice(chop).join(' ')}` : text;
  } while (outer.scrollHeight > outer.clientHeight && ++chop < words.length);
}

const resizeObserver = new ResizeObserver(() => {
  fit(document.getElementById('target'),
      'A few lines of text will overflow and run over, and the beginning will get chopped off.');  
});

resizeObserver.observe(document.getElementById('outer'));
#outer {
  width: 150px;
  height: 80px;
  overflow: hidden;
}
<div id="outer"><p id="target"></p></div>
Trevor Dixon
  • 23,216
  • 12
  • 72
  • 109
0

CSS option would never be like JS one. There is no way to write conditional css unfortunatelly. But using a fixed line height can manage the overflowing text to truncate.

Assumptions

  • Width is known
  • Line height is known

Here is an example:

:root {
  --line-height: 1.2rem;
}

html {
  max-width: 20rem;
  line-height: var(--line-height);
}

p {
  --truncate-after: 4;
    max-height: calc(var(--line-height) * var(--truncate-after));
  text-align: justify;
  position: relative;
  overflow: hidden;
  padding-right: 1rem;
  position: relative;
  display: block;
  height: fit-content;
  text-indent: 1rem;
}

p::after {
  content: "...";
  display: block;
  bottom: 3.83rem;
  position: absolute;
  height: 1rem;
  left: -1rem;
}
<p>
  <span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. In sint facilis explicabo voluptatum exercitationem earum. Quibusdam vitae, iusto temporibus corrupti tempore distinctio soluta reiciendis. Ab aspernatur facilis autem temporibus veniam.</span>
</p>

<p>
  <span>Lorem ipsum dolor sit, amet consectetur adipisicing elit.</span>
</p>

<p>
  <span>Lorem ipsum dolor sit, amet consectetur adipisicing elit. S'mores are tasty treats for around campfires.</span>
</p>
0

You can achieve this like following snippet:

  • Apply the height how many lines you need to show.
  • Hide after the lines.
  • Apply the pseudo ...

.start-ellipsis {
  height: 55px;
  overflow: hidden;
}
.start-ellipsis::before {
  content: "...";
  display: inline-block;
 }
<p class="start-ellipsis">contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source.</p>

Note:

  • Take care of the font size and font family as they affect the visual with your display. For eg. if you have set 55px height to show 3 lines and later you change the font family and its size then you need to change the height accordingly. So, best practice to define the height after finalizing your font family and font size and the line height.
  • This snippet may show/hide extra last line depending on different user's system font.
Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231