React-native-web: Text: implement `numberOfLines` > 1

Created on 8 Sep 2015  Â·  24Comments  Â·  Source: necolas/react-native-web

As far as I know, this is non trivial cross-browser but should be possible using document.createRange and getClientRects: https://developer.mozilla.org/en-US/docs/Web/API/Range

Most helpful comment

All 24 comments

+1

Webkit only, but:

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

http://hackingui.com/front-end/a-pure-css-solution-for-multiline-text-truncation/

Unfortunately, -webkit-line-clamp has poor i18n support. It doesn't work when the layout is RTL, or when the language has no spaces, and it doesn't render a language-appropriate equivalent of ….

I can try and take a shot at this but would like some comments in the approach I have in mind.

The gist of it is:

  • Use getBoundingClientRect to get a targetWidth
  • Use getComputedStyle to get the text styles
  • Use a Canvas and measureText method
  • Break the targeted text into lines with the specified "ellipsis" component/text

Any comments? Of course there are some performance considerations.

I think we can use https://github.com/necolas/react-native-web/issues/795 and compute the current number of lines via height / computed lineHeight, then restrict it.

will any of this solutions work with rnw? react-text-truncate or react-lines-ellipsis

-webkit-line-clamp has poor i18n support. It doesn't work when the layout is RTL, or when the language has no spaces

I just found this RTL demo and it seems it works better nowadays: https://codepen.io/nilsynils/pen/QKgJAY

Anyway, today's support seems to have improved.
Browser support is currently at 85% with the prefix.

I created #1090 just in case.

That demo doesn't show ellipsis for LTR and clips the Arabic text vertically. Still looks broken to me against that criteria alone

Okay... I'll keep using a fork then because I don't need RTL support.

Was able to get react-lines-ellipsis working using Platform.OS === 'web' - not the best solution, but a good work around.

@drumnation, thank you for tip - I can confirm it works.
Only thing to note - one should explicitly set width of parent, otherwise it replaces whole text with ellipsis only after first word

As I remember using getClientRects, it returned lines reliable. But the code would have to be rendered in script tag immediately after DOM for SSR.

@necolas Have you seen how ant-design's Input handle number of lines? Is that something that might work in rnw?

@tafelito that's an input component, not a text component

Sorry, this is the one I meant

https://pro.ant.design/components/Ellipsis/

I don't think so. That looks like it will be expensive to perform on many text nodes, and all the innerHTML calls are probably an XSS vector

After talking to a lot of people about this, including browser vendors, there is currently no good option. I'm going to include the webkit line-clamp implementation as a "kinda-works-for-a-common-case-only" stop-gap until browsers provide a standard solution.


cc @stubbornella

numberOfLines is a prop on React Native's Text component. It allows (rich) text to be truncated after a certain number of lines, with support for RTL languages and locale-specific equivalents to the ellipsis. This can't be practically implemented on the web. -webkit-line-clamp is a past attempt at doing this, but it has a lot of problems including limited browser support, requires opting into a old flexbox implementation (i.e., doesn't work with inline, inline-block, or inline-flex text), and has no RTL support. There are lots of bad JS hacks that attempt to do this, and its a popular request from web developers [[1](https://css-tricks.com/almanac/properties/l/line-clamp/)] [[2](https://css-tricks.com/line-clampin/)].

Examples of where this would be used on web: text in every Card on Twitter and Facebook. Cards in Tweets, Cards to display Profile information. Often we only want to display a couple of lines of contextual description that is then truncated in an accessible and friendly fashion.

https://facebook.github.io/react-native/docs/text#numberoflines

This makes a lot of sense to me and I brought it up to our engineers a
couple months ago. It’s something we probably need for virtual scroller.
Let me follow up again. How would you see it working? Same as line clamp?
On Fri, Dec 21, 2018 at 7:27 AM Nicolas Gallagher notifications@github.com
wrote:

After talking to a lot of people about this, including browser vendors,
there is currently no good option. I'm going to include the webkit
line-clamp implementation as a "kinda-works-for-a-common-case-only"

stop-gap until browsers provide a standard solution.

cc @stubbornella https://github.com/stubbornella

numberOfLines is a prop on React Native's Text component. It allows
(rich) text to be truncated after a certain number of lines, with support
for RTL languages and locale-specific equivalents to the ellipsis. This
can't be practically implemented on the web. -webkit-line-clamp is a past
attempt at doing this, but it has a lot of problems
https://medium.com/mofed/css-line-clamp-the-good-the-bad-and-the-straight-up-broken-865413f16e5
including limited browser support, requires opting into a old flexbox
implementation (i.e., doesn't work with inline, inline-block, or
inline-flex text), and has no RTL support. There are lots of bad JS hacks
that attempt to do this, and its a popular request from web developers [1
https://css-tricks.com/almanac/properties/l/line-clamp/] [2
https://css-tricks.com/line-clampin/].

Examples of where this would be used on web: text in every Card on Twitter
and Facebook. Cards in Tweets, Cards to display Profile information. Often
we only want to display a couple of lines of contextual description that is
then truncated in an accessible and friendly fashion.

https://facebook.github.io/react-native/docs/text#numberoflines

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/necolas/react-native-web/issues/13#issuecomment-449417403,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AACZ5sutxodzTi73dFHaG-sc_KNZSihmks5u7P3hgaJpZM4F5NG5
.

Yes please, something like line-clamp with localization considerations built-in. Thank you :)

What are the localization considerations? (Thank you for catching me up!)
On Fri, Dec 21, 2018 at 7:38 AM Nicolas Gallagher notifications@github.com
wrote:

Yes please, something like line-clamp with localization considerations
built-in. Thank you :)

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/necolas/react-native-web/issues/13#issuecomment-449420443,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AACZ5tF5Tr2yYcD6gukPBVugPOxk7wAEks5u7QCIgaJpZM4F5NG5
.

It needs to support RTL languages and I believe it needs to provide language-specific symbols to indicate "truncation". Not every language can use ellipsis. But I don't know the extent of the complexities involved in localization or accessibility (should screen readers read the full text or the truncated text?), just that -webkit-line-clamp falls well short

I wonder if there is a good resource for reading about the failings of
-webkit-line-clamp? /me goes to search
On Fri, Dec 21, 2018 at 7:46 AM Nicolas Gallagher notifications@github.com
wrote:

It needs to support RTL languages and I believe it needs to provide
language-specific symbols to indicate "truncation". Not every language can
use ellipsis. But I don't know the extent of the complexities involved in
localization or accessibility (should screen readers read the full text or
the truncated text?), just that -webkit-line-clamp falls well short

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/necolas/react-native-web/issues/13#issuecomment-449422697,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AACZ5u5TuUV4mZVHE3zcMWINYyWUD9Ciks5u7QJogaJpZM4F5NG5
.

Was this page helpful?
0 / 5 - 0 ratings