vercel / satori

Enlightened library to convert HTML and CSS to SVG

Home Page:https://og-playground.vercel.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`lineClamp` / `textOverflow` incorrectly overflows after first word in a line

notjosh opened this issue Β· comments

Bug report

Description / Observed Behavior

πŸ‘‹ Hiya!

I was experimenting with lineClamp + textOverflow to create some OpenGraph images and noticed that sometimes (say, 2% of cases) the ellipsis would expand beyond the bounds. At first I figured it was some measurement problem (fonts are hard!), but it seems to be deliberate, however it appears to deviate from how browsers handle the same case.

I've created a couple of tests in different browsers (HTML+CSS), using the words "on Kickstarter" at various container widths to observe the behaviour. In Safari and Firefox, we can see the first letter ("o") will always be rendered, and then every other character can be omitted(/replace with ellipsis):

image

However Satori will include the first letter of each word, not just the first word of a line, so we get something like (note: I've kept overflow visible here to make the problem more obvious):

image

Specifically: we can see the "on K..." rendering the "K" when there isn't room and pushes the ellipsis outside of the bounds, which differs from browsers. (And to be clear: the "o" rendering without room is expected - only the "K" is incorrect)

Expected Behavior

I updated calcEllipsis() (in src/text/index.ts) to include a check for explicitly being the first word of a line, and we can achieve the same behaviour as browsers:

image

Specifically: instead of rendering the "K" and overflowing, we simply render the ellipsis. As before, the "o" will always render as the first word of a line.

Reproduction

repro playground - depending your browser/fonts, you might need to tweak some of the sizes to find the right breakpoints...but you'll get the idea.

Additional Context

The comments in the code refer to "The first character or atomic inline-level element on a line must be clipped rather than ellipsed", so obviously some consideration had been made for this feature before, but I think the correct interpretation is what the browsers do - second and subsequent words can be omitted if they don't fit.

And for completeness, when lineClamp: >= 2, we'll need to make sure the first word of each line has at least one character. That seems easy enough to detect though?

I'm happy to put up a PR to implement the change, unless there's some intended reason for the current behaviour. Let me know!

Excellent! I really appreciate you taking the time to uncover and resolve this issue.