Authentic people growing open source code with taste

New Feature: line-clamp

A new feature, line-clamp, has been added in WeasyPrint.

line-clamp has been added thanks to the financial support of Expert Germany. It has been a real pleasure to develop this feature with them.

You would love to get a new feature, a bug fix, or some support on WeasyPrint? Don’t hesitate to get in touch with us! Or if you simply want to see the project grow beautifully, you can donate on OpenCollective 😉.

Why line-clamp?

line-clamp is a shorthand property that is very useful to limit the height of blocks, and avoid strange layouts when the content is longer than what we expected.

For example: let’s say you want to render a poster to present a company.

Good example of a poster describing CourtBouillon 😁

If the description of the company comes from an external source, it may not fit in the poster. And the result can be awful…

Bad example of a poster describing CourtBouillon 😒, first page Bad example of a poster describing CourtBouillon 😒, second page

Of course, you can’t have a second page for this poster, so you have to find a better solution.

The best solution was to use overflow: hidden, to cut the block when the text is too long.

A poster describing CourtBouillon, with overflow property set to hidden

The result is not perfect. It is possible to set the line height and have a block height set accordingly. But this is not really reliable, and it should be possible to find something better. That’s where line-clamp can be useful.

How to use line-clamp?

line-clamp is actually a shortand property for 3 different properties: max-lines, block-ellipsis, continue.

continue defines what happens when a block is fragmented. What’s a fragmented block? It’s a block that’s split into multiple smaller blocks: that’s what happens when the beginning of a block is at the end of a page, and the end of the block is at the beginning of the next page.

The default value of continue is auto, and it makes the end of the block to be displayed on the next page. The new value that’s now supported is discard, and it prevents the end of the block to be displayed at all. That’s very useful when you want your content to fit in a page, and it doesn’t cut the lines in the middle as it’s done with overflow.

A poster describing CourtBouillon, with continue property set to discard

The problem with this that the content is cut with no visual indication. What if there was a way to add an ellipsis at the end of the last line?

Good news: block-ellipsis is the property we want! We can set the auto value to get the default ellipsis character, or a random string if you prefer something else.

A poster describing CourtBouillon, with ellipsis

The last property handled by line-clamp is max-lines. This property lets you define how many lines are allowed in a block before it’s split, even if the block didn’t reach the end of the page.

max-lines is particularly useful when used with continue: discard: it gives a simple way to truncate a block after a given number of lines, even if you don’t have the height of each line. And of course, block-ellipsis also works in this case!

A poster describing CourtBouillon, with max-lines and block-ellipsis set

Shorthand, limitations, testing

line-clamp gives a short way to set a maximum number of lines and optionally give a string used as ellipsis. It also unconditionally sets continue to discard.

The three properties and the line-clamp shorthand are now supported by WeasyPrint. It works pretty well for many use cases, but the current implementation also has some limitations:

  • Setting max-lines always sets continue to discard too.
  • block-ellipsis only works if the last text of the block is cut. For example, if a list is split between two list items, no ellipsis is displayed.
  • max-lines doesn’t work yet with nested blocks.

The feature can be tested on the current master branch. You didn’t try the next version of WeasyPrint yet? That’s a good reason to give a look right now! It has also been backported to the Cairo version (52.3), enjoy this new release.