Jose A.
Jose A.

Reputation: 553

line clamp (webkit) not working in safari

    display: -webkit-box;
  -webkit-line-clamp: 5;
  line-clamp: 5;
  -webkit-box-pack: end;
  text-overflow: ellipsis;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-align: left;

I have this to a P tag but is not working in safari, any other browser works fine

Upvotes: 18

Views: 32822

Answers (5)

Abtin Gramian
Abtin Gramian

Reputation: 1780

I was experiencing this issue with webkit line clamp not working on Safari for a section with nested rich text elements similar to the code snippet below:

.rich-text-container {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
<div class="rich-text-container">
  <h2>Heading</h2>
  <p>Paragraph content.</p>
  <h4>Another heading</h4>
  <p>More paragraph content</p>
  <ul>
    <li>Unordered list item</li>
  </ul>
  <ol>
    <li>Ordered list item</li>
  </ol>
</div>

To get the line clamping in Safari to behave similarly to Chrome, the most straightforward workaround I found is to toggle a maxHeight value using JavaScript. The value should be set to the same or a slightly higher height than is actually required so that it doesn't interfere with the behavior in Chrome and cut off any of the bottom of the last line.

In my case, multiplying the number of lines to clamp by 3.25 and using em for units seems to work well enough (ex: for -webkit-line-clamp: 2 using maxHeight: 6.5em).

The limitation of this workaround is that you do not get the ellipsis behavior at the end of the last line in Safari as you would in Chrome.

Here is an example code snippet with the workaround:

var isClamping = false;

function toggleClamping() {
  isClamping = !isClamping;
  document.getElementById('toggleButton').innerText = isClamping ? 'Show more' : 'Show less';
  document.getElementById('textDiv').style.webkitLineClamp = isClamping ? '2' : '';
  document.getElementById('textDiv').style.maxHeight = isClamping ? '6.5em' : '';
}
.rich-text-container {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
<div id="textDiv" class="rich-text-container">
  <h2>Heading</h2>
  <p>Paragraph content.</p>
  <h4>Another heading</h4>
  <p>More paragraph content</p>
  <ul>
    <li>Unordered list item</li>
  </ul>
  <ol>
    <li>Ordered list item</li>
  </ol>
</div>
<button id="toggleButton" type="button" onclick="toggleClamping()">
    Show less
</button>

Note: the webkit line clamping behavior in Safari only seems to have issues when the line clamping is set on a parent element with nested elements. Setting line clamping on individual html elements works fine in Safari as shown in the example below:

.rich-text-element {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
<p class="rich-text-element">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ac commodo nulla. Suspendisse eu vehicula libero. Donec rutrum velit in turpis blandit condimentum. Nullam ullamcorper varius elit non venenatis. In faucibus metus in rhoncus mollis. Mauris
  blandit tincidunt urna nec sodales. Nunc et justo sagittis, bibendum risus euismod, vehicula odio. Nam a fermentum ex, et luctus erat. Aenean ac arcu lobortis, imperdiet arcu in, maximus leo. Quisque dictum dignissim magna, efficitur tincidunt ligula
  ornare non. Quisque mi mauris, pellentesque pharetra mi ac, rutrum luctus diam. Sed gravida nunc ac mauris sodales vestibulum.
  <p/>

Upvotes: -2

Andrei Sumin
Andrei Sumin

Reputation: 41

One more thing about safari: this hack

.text {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;

    * {
        display: inline;
    }
}

won't work in case you need to have text-align: justify;. So just a JS solution can be applied in this case.

Upvotes: 3

srg
srg

Reputation: 399

Multi "line clamp" (webkit) not working in safari, if use not inline elements. This example works in chrome (v100) but not in safari (v15.1).

div.hide {
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  display: -webkit-box;
  overflow: hidden;
}

button {
  margin-top: 16px;
}
<div id="container" class="hide">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Officiis ducimus magni, commodi nesciunt tempora unde ipsa repellendus impedit recusandae rem aliquid, alias illum sunt consequatur animi laudantium distinctio odit explicabo.</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nobis totam harum laudantium excepturi repellendus similique non est incidunt vero officia saepe error reprehenderit quibusdam, ex tenetur autem impedit soluta culpa.</p>
</div>

<button onclick="document.querySelector('#container').classList.toggle('hide')">Click me!</button>

But you can set display: inline; for paragraphs, then hiding will work correctly. For indentation you can add a pseudo-element.

div.hide {
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  display: -webkit-box;
  overflow: hidden;
}

p {
  display: inline;
}

p::after {
  content: " \A\A";
  white-space: pre;
}

button {
  margin-top: 16px;
}
<div id="container" class="hide">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Officiis ducimus magni, commodi nesciunt tempora unde ipsa repellendus impedit recusandae rem aliquid, alias illum sunt consequatur animi laudantium distinctio odit explicabo.</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nobis totam harum laudantium excepturi repellendus similique non est incidunt vero officia saepe error reprehenderit quibusdam, ex tenetur autem impedit soluta culpa.</p>
</div>

<button onclick="document.querySelector('#container').classList.toggle('hide')">Click me!</button>

Unfortunately, this is a hack and may not work in all cases. However, using display: -webkit-box and -webkit-line-clamp: 3 for hiding is also a hack which is missing in the spec, which is probably why safari does not support it.

The most correct and reliable solution is to use js for hiding

Upvotes: 29

CopyLeft
CopyLeft

Reputation: 329

The <p> tag often times has browser-defined margins by default, or if you use a CSS library like Bootstrap, so that could be causing your -webkit-line-clamp on Safari to seem like it's not working or is buggy.

In my case, I had a <p> with a pre-defined margin-bottom value inside of a <div> that caused the subsequent lines past the -webkit-line-clamp limit to be revealed.

On Chrome & Firefox, the following works fine:

<div class="parent">
    <p>Some really long string of text here that eventually gets clamped</p>
</div>
.parent {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 1;
    overflow: hidden;
}

On Safari, since the inner <p> had a margin-bottom, it affected the height of the parent <div> by making the parent taller, and revealing the subsequent lines.

So, my cross-browser solution was:

.parent {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 1;
    overflow: hidden;
}

.parent > p {
    margin-bottom: 0;
}

Upvotes: 1

J Davies
J Davies

Reputation: 289

line clamp does work on safari.

It doesn't work on inner block level elements: CSS line-clamp does not work in Safari on inner block level elements

.line-clamp{
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden; 
  text-overflow: ellipsis;
  overflow: hidden;
  text-align: left;
}
<p class="line-clamp">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>

Upvotes: 2

Related Questions