You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Text descender characters cut-off after upgrade from 0.76.1 to 0.78 with lineHeight the same as fontSize #49886
Hey @a-klotz-p8,
Thank you for bringing this issue to our attention. I have been able to reproduce the problem on Android (both new and old architecture). However, the issue does not appear to occur on iOS (both new and old architecture), where everything is functioning as expected.
TLDR: Using a line-height the same as font-size will cause clipping. Previously this was at the top, and now it's centered.
This is because of changes related to how we distribute line-height, to act more like web. A similar change may be coming to iOS, that @cipolleschi has been looking at getting merged. #29507
Previously, React Native on Android would arbitrarily shift text up, when line-height did not provide enough space. So, we could cut off ascenders, depending on the font, or could get some really funky results when certain unicode or emojis was used.
Now, React Native, like web, will center text within the the line box, instead of shifting the text upward. Unfortunately, unlike web, React Native still enforces that glyphs overflowing the bounds of the Text container will be clipped. This may change in the future, since having a line-height smaller than allowable space can sometimes be useful, even if it is currently (and... previously) frought, and can lead to different kinds of clipping.
Here's an example of what this looks like on web, where we mark a paragraph with overflow: hidden. We see the same issue, because the line-height does not provide enough space for the glyph, but now, we "distribute" the clipping to both the top and bottom, instead of just the top.
TLDR: Using a line-height the same as font-size will cause clipping. Previously this was at the top, and now it's centered.
This is because of changes related to how we distribute line-height, to act more like web. A similar change may be coming to iOS, that @cipolleschi has been looking at getting merged. #29507
Previously, React Native on Android would arbitrarily shift text up, when line-height did not provide enough space. So, we could cut off ascenders, depending on the font, or could get some really funky results when certain unicode or emojis was used.
Now, React Native, like web, will center text within the the line box, instead of shifting the text upward. Unfortunately, unlike web, React Native still enforces that glyphs overflowing the bounds of the Text container will be clipped. This may change in the future, since having a line-height smaller than allowable space can sometimes be useful, even if it is currently (and... previously) frought, and can lead to different kinds of clipping.
Here's an example of what this looks like on web, where we mark a paragraph with overflow: hidden. We see the same issue, because the line-height does not provide enough space for the glyph, but now, we "distribute" the clipping to both the top and bottom, instead of just the top.
Thanks for the explanation. I guess in the meantime I am going to use paddingVertical with negative marginVertical until react-native Text allows overflowing glyphs.
@NickGerleman
Using the paddingVertical with negative marginVertical fixed the issue but with this having alignItems: 'baseline' does not work anymore to have text of different sizes on the same baseline see:
TLDR: Using a line-height the same as font-size will cause clipping. Previously this was at the top, and now it's centered.
This is because of changes related to how we distribute line-height, to act more like web. A similar change may be coming to iOS, that @cipolleschi has been looking at getting merged. #29507
Previously, React Native on Android would arbitrarily shift text up, when line-height did not provide enough space. So, we could cut off ascenders, depending on the font, or could get some really funky results when certain unicode or emojis was used.
Now, React Native, like web, will center text within the the line box, instead of shifting the text upward. Unfortunately, unlike web, React Native still enforces that glyphs overflowing the bounds of the Text container will be clipped. This may change in the future, since having a line-height smaller than allowable space can sometimes be useful, even if it is currently (and... previously) frought, and can lead to different kinds of clipping.
Here's an example of what this looks like on web, where we mark a paragraph with overflow: hidden. We see the same issue, because the line-height does not provide enough space for the glyph, but now, we "distribute" the clipping to both the top and bottom, instead of just the top.
@NickGerleman The problem with this approach is that, as you mention, it doesn't behave like the web despite that seemingly being the intention.
I'm using a font that has very small descenders (Ilisarniq) which makes it very suitable for having the same line-height as font-size. There's nothing typographically incorrect with doing so. It looks good, reads well etc. Except now, it's getting clipped everywhere since we upgraded to 0.79.
I don't mind the change you made per se, I mean, it makes sense - BUT the clipping doesn't make sense as it doesn't clip on web or on iOS, AND there's no workaround available either. The only way I can solve this is by increasing line-height which in my case actually reduces readability and messes with the overall design.
Any idea? I am having this issue with the Playwrite AT font on iOS. specifically with the ascender of the capital V when in italic. it gets cropped on the right when I align the text to the right. The only workaround is to insert a white (bg-color) character after...
Any idea? I am having this issue with the Playwrite AT font on iOS. specifically with the ascender of the capital V when in italic. it gets cropped on the right when I align the text to the right. The only workaround is to insert a white (bg-color) character after...
I ended up asking the foundry if they were kind enough to adjust the font itself, which they did. I'm guessing that's not going to help you :/
My goodness. This is major flaw since it effects something so basic as text rendering. I'm surprised it has gone unaddressed for so long. I don't see any reason given here why the clipping happens. Why not just render the full glyph? Is there something about React Native rendering that fundamentally prevents this?
Any idea? I am having this issue with the Playwrite AT font on iOS. specifically with the ascender of the capital V when in italic. it gets cropped on the right when I align the text to the right. The only workaround is to insert a white (bg-color) character after...
I ended up asking the foundry if they were kind enough to adjust the font itself, which they did. I'm guessing that's not going to help you :/
what adjustments did they make? I tried changing the typoAscender and typoDescender in the OS2 Table but this leads to the text not being centered correctly anymore. Do you know what changes they made exactly?
Any idea? I am having this issue with the Playwrite AT font on iOS. specifically with the ascender of the capital V when in italic. it gets cropped on the right when I align the text to the right. The only workaround is to insert a white (bg-color) character after...
I ended up asking the foundry if they were kind enough to adjust the font itself, which they did. I'm guessing that's not going to help you :/
what adjustments did they make? I tried changing the typoAscender and typoDescender in the OS2 Table but this leads to the text not being centered correctly anymore. Do you know what changes they made exactly?
I have no idea. I tried to do it myself first with the help of ChatGPT but failed.
There's a specific Android 0.78+ interaction here: when lineHeight === fontSize, the advance-box height equals the font size, but glyph ink (descenders, accents) extends below the baseline by |descender| pts. iOS's NSLayoutManager absorbs the overshoot via line-fragment padding; Android's TextPaint reports the same metrics but the container is still sized to the advance box, so ink lands outside the clip rect. Looks related to #15114, #53286, #56402.
Two workarounds that have worked for me while this gets sorted upstream:
Pad by actual ink bounds — read descender / ascender via native font metrics and apply paddingBottom / paddingTop so the ink has room to land. <InkSafeText strict> in expo-pretext@1.0 wraps this up.
Render line-by-line — emit one <Text> per computed line with enough vertical slot per line. <SafeText> does this and sidesteps RN's container-sizing mismatch entirely.
Neither is a fix to RN itself — strictly workarounds. Happy to dig in if anyone's still blocked.
Activity
sarthak-playvision commentedon Mar 10, 2025
Hey @a-klotz-p8,
Thank you for bringing this issue to our attention. I have been able to reproduce the problem on Android (both new and old architecture). However, the issue does not appear to occur on iOS (both new and old architecture), where everything is functioning as expected.
a-klotz-p8 commentedon Mar 10, 2025
Yes, for me this issue only occurred on Android. Good to hear you where able to reproduce it.
NickGerleman commentedon Mar 10, 2025
TLDR: Using a
line-heightthe same asfont-sizewill cause clipping. Previously this was at the top, and now it's centered.This is because of changes related to how we distribute line-height, to act more like web. A similar change may be coming to iOS, that @cipolleschi has been looking at getting merged. #29507
Previously, React Native on Android would arbitrarily shift text up, when
line-heightdid not provide enough space. So, we could cut off ascenders, depending on the font, or could get some really funky results when certain unicode or emojis was used.Now, React Native, like web, will center text within the the line box, instead of shifting the text upward. Unfortunately, unlike web, React Native still enforces that glyphs overflowing the bounds of the
Textcontainer will be clipped. This may change in the future, since having aline-heightsmaller than allowable space can sometimes be useful, even if it is currently (and... previously) frought, and can lead to different kinds of clipping.Here's an example of what this looks like on web, where we mark a paragraph with
overflow: hidden. We see the same issue, because theline-heightdoes not provide enough space for the glyph, but now, we "distribute" the clipping to both the top and bottom, instead of just the top.a-klotz-p8 commentedon Mar 11, 2025
Thanks for the explanation. I guess in the meantime I am going to use paddingVertical with negative marginVertical until react-native Text allows overflowing glyphs.
a-klotz-p8 commentedon Mar 11, 2025
@NickGerleman
Using the paddingVertical with negative marginVertical fixed the issue but with this having alignItems: 'baseline' does not work anymore to have text of different sizes on the same baseline see:
snack reproducer:
https://snack.expo.dev/@alex_p8/jealous-red-donut
Is there a better way to fix this?
ddx533534 commentedon Mar 12, 2025
I tried this code example, but this issue didn't occur on Android device~
a-klotz-p8 commentedon Mar 12, 2025
The original Issue with the text being cut off? On what device did you run it and was it in a expo snack or from the Github replication repo?
AdamGerthel commentedon Aug 7, 2025
@NickGerleman The problem with this approach is that, as you mention, it doesn't behave like the web despite that seemingly being the intention.
I'm using a font that has very small descenders (Ilisarniq) which makes it very suitable for having the same line-height as font-size. There's nothing typographically incorrect with doing so. It looks good, reads well etc. Except now, it's getting clipped everywhere since we upgraded to 0.79.
I don't mind the change you made per se, I mean, it makes sense - BUT the clipping doesn't make sense as it doesn't clip on web or on iOS, AND there's no workaround available either. The only way I can solve this is by increasing line-height which in my case actually reduces readability and messes with the overall design.
alanschwarz commentedon Sep 5, 2025
Any idea? I am having this issue with the Playwrite AT font on iOS. specifically with the ascender of the capital V when in italic. it gets cropped on the right when I align the text to the right. The only workaround is to insert a white (bg-color) character after...
AdamGerthel commentedon Sep 5, 2025
I ended up asking the foundry if they were kind enough to adjust the font itself, which they did. I'm guessing that's not going to help you :/
Lomacar commentedon Nov 13, 2025
My goodness. This is major flaw since it effects something so basic as text rendering. I'm surprised it has gone unaddressed for so long. I don't see any reason given here why the clipping happens. Why not just render the full glyph? Is there something about React Native rendering that fundamentally prevents this?
a-klotz-p8 commentedon Nov 20, 2025
what adjustments did they make? I tried changing the typoAscender and typoDescender in the OS2 Table but this leads to the text not being centered correctly anymore. Do you know what changes they made exactly?
AdamGerthel commentedon Nov 20, 2025
I have no idea. I tried to do it myself first with the help of ChatGPT but failed.
albertorg-ey commentedon Jan 20, 2026
Any updates or workarounds?
JubaKitiashvili commentedon Apr 19, 2026
There's a specific Android 0.78+ interaction here: when
lineHeight === fontSize, the advance-box height equals the font size, but glyph ink (descenders, accents) extends below the baseline by|descender|pts. iOS'sNSLayoutManagerabsorbs the overshoot via line-fragment padding; Android'sTextPaintreports the same metrics but the container is still sized to the advance box, so ink lands outside the clip rect. Looks related to #15114, #53286, #56402.Two workarounds that have worked for me while this gets sorted upstream:
descender/ascendervia native font metrics and applypaddingBottom/paddingTopso the ink has room to land.<InkSafeText strict>inexpo-pretext@1.0wraps this up.<Text>per computed line with enough vertical slot per line.<SafeText>does this and sidesteps RN's container-sizing mismatch entirely.Neither is a fix to RN itself — strictly workarounds. Happy to dig in if anyone's still blocked.
Fix Android text descender clipping with tight lineHeight (react#57115)