Skip to content

Text descender characters cut-off after upgrade from 0.76.1 to 0.78 with lineHeight the same as fontSize #49886

Closed

Description

@a-klotz-p8

Description

After upgrading to the latest RN (0.78) I noticed that text descenders are cut off on Android while on iOS the text looks normal.

iOS:

Image

Android:

Image

Steps to reproduce

  1. install the code from https://github.com/a-klotz-p8/TextDescendersIssue/tree/main
  2. run on android

alternatively just init a new latest RN project and add Text components with the same lineHeight and fontSize.

React Native Version

0.78.0

Affected Platforms

Runtime - Android

Output of npx @react-native-community/cli info

System:
  OS: macOS 15.3.1
  CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
  Memory: 4.71 GB / 64.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 23.3.0
    path: /usr/local/bin/node
  Yarn: Not Found
  npm:
    version: 10.9.0
    path: /usr/local/bin/npm
  Watchman:
    version: 2024.12.02.00
    path: /usr/local/bin/watchman
Managers:
  CocoaPods:
    version: 1.15.2
    path: /usr/local/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.2
      - iOS 18.2
      - macOS 15.2
      - tvOS 18.2
      - visionOS 2.2
      - watchOS 11.2
  Android SDK:
    API Levels:
      - "34"
      - "35"
    Build Tools:
      - 32.0.0
      - 33.0.0
      - 34.0.0
      - 35.0.0
    System Images:
      - android-30 | Google Play Intel x86 Atom
      - android-31 | Google APIs Intel x86_64 Atom
      - android-33 | Google Play Intel x86_64 Atom
      - android-34 | Intel x86_64 Atom
      - android-34 | Google APIs Intel x86_64 Atom
      - android-34 | Google Play Intel x86_64 Atom
      - android-35 | Google Play Intel x86_64 Atom
    Android NDK: Not Found
IDEs:
  Android Studio: 2024.1 AI-241.18034.62.2412.12266719
  Xcode:
    version: 16.2/16C5032a
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.13
    path: /usr/bin/javac
  Ruby:
    version: 3.3.5
    path: /usr/local/opt/ruby/bin/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 15.0.1
    wanted: 15.0.1
  react:
    installed: 19.0.0
    wanted: 19.0.0
  react-native:
    installed: 0.78.0
    wanted: 0.78.0
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: true
  newArchEnabled: true

Stacktrace or Logs

no crash

Reproducer

https://github.com/a-klotz-p8/TextDescendersIssue/tree/main

Screenshots and Videos

Image

Activity

  1. sarthak-playvision commented on Mar 10, 2025

    @sarthak-playvision

    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.

  2. a-klotz-p8 commented on Mar 10, 2025

    @a-klotz-p8
    ContributorAuthor

    Yes, for me this issue only occurred on Android. Good to hear you where able to reproduce it.

  3. NickGerleman commented on Mar 10, 2025

    @NickGerleman
    Contributor

    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.

    Image

    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.

    Image
  4. a-klotz-p8 commented on Mar 11, 2025

    @a-klotz-p8
    ContributorAuthor

    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.

    Image

    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.

    Image

    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.

  5. a-klotz-p8 commented on Mar 11, 2025

    @a-klotz-p8
    ContributorAuthor

    @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:

    Image

    snack reproducer:
    https://snack.expo.dev/@alex_p8/jealous-red-donut

    Is there a better way to fix this?

  6. ddx533534 commented on Mar 12, 2025

    @ddx533534

    I tried this code example, but this issue didn't occur on Android device~

  7. a-klotz-p8 commented on Mar 12, 2025

    @a-klotz-p8
    ContributorAuthor

    I tried this code example, but this issue didn't occur on Android device~

    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?

  8. AdamGerthel commented on Aug 7, 2025

    @AdamGerthel

    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.

    Image

    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.

    Image

    @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.

  9. alanschwarz commented on Sep 5, 2025

    @alanschwarz

    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...

  10. AdamGerthel commented on Sep 5, 2025

    @AdamGerthel

    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 :/

  11. Lomacar commented on Nov 13, 2025

    @Lomacar

    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?

  12. a-klotz-p8 commented on Nov 20, 2025

    @a-klotz-p8
    ContributorAuthor

    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?

  13. AdamGerthel commented on Nov 20, 2025

    @AdamGerthel

    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.

  14. albertorg-ey commented on Jan 20, 2026

    @albertorg-ey

    Any updates or workarounds?

  15. JubaKitiashvili commented on Apr 19, 2026

    @JubaKitiashvili

    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:

    1. 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.
    2. 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions