question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

The line breaks are rendered with too much vertical space

See original GitHub issue

Decision Table

  • My issue does not look like “The HTML attribute ‘xxx’ is ignored” (unless we claim support for it)
  • My issue does not look like “The HTML element <yyy> is not rendered”

Good Faith Declaration

Description

The line breaks are rendered with too much vertical space. Below is the html that I am trying to render:

<div>asd</div>
<div><br></div>
<div>asda</div>
<div>as</div>
<div><br></div>
<div>asda</div>
<div><br></div>
<div>asd</div>
<div><br></div>

I have an alarm app where user can enter formatted notes for each alarm. I am using react-native-rich-text-editor to allow user to enter the notes. The above html is generated by the react-native-rich-text-editor package. Below is how it looks in the editor

image

Below is how it looks when rendered using react-native-render-html. It is rendered in the “Notes” field. Notice the vertical space around the line breaks.

image

Below is how it is rendered on an html editor on web

image

Below is how I am rendering the html

<RenderHtml
                  contentWidth={width}
                  source={{ html: props.notes }}
                  renderersProps={renderersProps}
                  enableExperimentalMarginCollapsing={true}
                />

It is quite evident that there is a lot empty space vertically around the the line breaks.

Is there a way to reduce this vertical spacing. I tried using custom renderer for br tags but I guess that is not currently supported.

React Native Information

System:
    OS: macOS 11.0.1
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 2.79 GB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 12.16.1 - ~/.nvm/versions/node/v12.16.1/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 6.13.4 - ~/.nvm/versions/node/v12.16.1/bin/npm
    Watchman: Not Found
  Managers:
    CocoaPods: 1.10.1 - /Users/varungupta/.rvm/rubies/ruby-2.4.1/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 14.2, DriverKit 20.0, macOS 11.0, tvOS 14.2, watchOS 7.1
    Android SDK:
      API Levels: 21, 23, 24, 25, 26, 27, 28, 29, 30
      Build Tools: 23.0.1, 25.0.0, 26.0.1, 26.0.2, 27.0.1, 27.0.3, 28.0.3, 29.0.2, 30.0.2
      System Images: android-26 | Google APIs Intel x86 Atom, android-26 | Google Play Intel x86 Atom, android-28 | Google APIs Intel x86 Atom, android-28 | Google Play Intel x86 Atom, android-29 | Google Play Intel x86 Atom, android-30 | Google Play Intel x86 Atom, android-S | Google APIs Intel x86 Atom_64, android-S | Google Play Intel x86 Atom_64
      Android NDK: 15.2.4203891
  IDEs:
    Android Studio: 2020.3 AI-203.7717.56.2031.7583922
    Xcode: 12.2/12B45b - /usr/bin/xcodebuild
  Languages:
    Java: 1.8.0_144 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: Not Found
    react-native: 0.64.0 => 0.64.0
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

RNRH Version

6.0.5

Tested Platforms

  • Android
  • iOS
  • Web
  • MacOS
  • Windows

Reproduction Platforms

  • Android
  • iOS
  • Web
  • MacOS
  • Windows

Minimal, Reproducible Example

https://snack.expo.dev/bBGR1YQPE

Additional Notes

No response

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:9

github_iconTop GitHub Comments

4reactions
jsamrcommented, Aug 29, 2021

Findings

Ignore my previous comment regarding the HTML standard. The issue stems from how React Native renders an empty Text element inside a View :

<View style={{backgroundColor: 'yellow'}}>
  <Text></Text>
</View>

image

Instead of an zero-height line.

Similarly,

<View style={{backgroundColor: 'yellow'}}>
  <Text>{"\n"}</Text>
</View>

image

So React Native always inserts an implicit line break after empty Text which is not how <br> behaves.

Extracted Rules

  • <br> tags should be rendered as empty text when they close a React Native textual formatting context (e.g. when they are the last child of a TPhrasing node which has no TPhrasing ancestor).
  • empty TText nodes should always be ignored instead of being rendered as empty Text (otherwise, an implicit line break will be inserted).

Workaround

In the meantime, you can implement a hacky workaround via custom renderer:

import * as React from 'react';
import {ScrollView, StyleSheet, useWindowDimensions, Text} from 'react-native';
import HTML from 'react-native-render-html';

function isBrTNode(tnode) {
  return (
    ((tnode.tagName === null && tnode.type === 'phrasing') ||
      tnode.tagName === 'br') &&
    tnode.children.every(isBrTNode)
  );
}

const renderers = {
  div: ({TDefaultRenderer, tnode, ...props}) => {
    if (tnode.children.length === 1 && isBrTNode(tnode.children[0])) {
      return <Text />;
    }
    return <TDefaultRenderer tnode={tnode} {...props} />;
  },
};

const html = `
<div>asd</div>
<div><br></div>
<div>asda</div>
<div>as</div>
<div><br></div>
<div>asda</div>
<div><br></div>
<div>asd</div>
<div><br></div>
`;

export default function App() {
  const {width: contentWidth} = useWindowDimensions();
  return (
    <ScrollView contentContainerStyle={styles.container}>
      <HTML
        defaultTextProps={{selectable: true}}
        contentWidth={contentWidth}
        source={{html}}
        renderers={renderers}
      />
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    flexGrow: 1,
  },
});

3reactions
jsamrcommented, Aug 29, 2021

The fix has been tested and validated. To be clear, the issue identified in the aforementioned React Native bug was not the reason for this specific bug. It was react-native-render-html which didn’t honor the HTML spec. I added a section in the docs which covers those two text-related issues.

To sum things up, enableExperimentalBRCollapsing addresses this reported bug related to <br> tags, and enableExperimentalGhostLinesPrevention addresses the bug I reported in React Native issue tracker.

Those props are now available in the 6.1.0 release. Please let me know if it works for you! (a thumb is enough). Below are my visual tests:

With enableExperimentalBRCollapsing (v6.1.0) Without enableExperimentalBRCollapsing (v6.1.0)

with-flags

without-flags

Read more comments on GitHub >

github_iconTop Results From Across the Web

Line break after \item, vertical spacing - LaTeX Stack Exchange
I think the idea is clear. Alas, there's too little vertical space after the description label. How can I set the vertical space...
Read more >
4.6. Precise Spacing and Layout - HTML & XHTML - O'Reilly
The clear attribute​​ Sometimes you'd rather the current text flow resume below any tables or images currently blocking the left or right margin....
Read more >
WordPress: adding extra line breaks, vertical space and more
First: remember that you can always get less space by using “shift” with the “return” (or “enter”) key. that will give you one...
Read more >
Line-breaks between divs render a space. How to eliminate it ...
Try to float:left your divs instead. · which browser are you having an issue with? · 1 · If it is not too...
Read more >
Where Lines Break is Complicated. Here's all the ... - CSS-Tricks
Other HTML Stuff · The <br> element will break a line wherever it renders. Unless it's display: none; ! · The <wbr> element...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found