React-native-render-html: TextAlign does not work on android

Created on 10 Mar 2020  路  9Comments  路  Source: meliorence/react-native-render-html

Is this a bug report or a feature request?

Bug report

Have you read the guidelines regarding bug report?

Yes

Have you read the documentation in its entirety?

Yes

Have you made sure that your issue hasn't already been reported/solved?

There is a question regarding this, but it has not been reported as a bug

Is the bug specific to iOS or Android? Or can it be reproduced on both platforms?

The bug only exists on android

Is the bug reproductible in a production environment (not a debug one)?

I have reproduced the bug in all my environments.

Have you been able to reproduce the bug in the provided example?

No. I reproduced it several times with different configurations in my project, as well as seeing others talking about the issue. (https://github.com/archriss/react-native-render-html/issues/264)

Environment

Environment:
Expo: v35.0.0
React: 16.0.0-beta.5
React native: 0.59 (according to expo documentation)
react-native-render-html: 4.2.0

Target Platform:
Android 9.0

Steps to Reproduce

  1. pass valid html to the html prop. Examples:
  2. <div>this is a div test<div>
  3. <p>this is a paragraph test<p>
  4. pass styles to baseFontStyle and/or tagStyles. Examples:
  5. baseFontStyle: { textAlign: 'center' }
  6. tagStyles: { div: { textAlign: 'center' }, p: { textAlign: 'center' }}

Expected Behavior

Expected text from html elements to align according to the passed style. Also expected that adding the style to the html before it is passed should work: <div style="text-align: center">some text here</div>

Actual Behavior

The value of text-align is never used.
Text will align center if it can fit on 1 line, regardless of the value passed to text-align.
Text will align left if it needs multilines, regardless of the value passed to text-align.

This is an example with multiline text
This is an example with a short text.

As mentioned above, I also expected <div style="text-align: center">some text here</div> to work, but it does not. However it will work if we switch div to a paragraph like so: <p style="text-align: center">some text here</p>

This is currently the only workaround I have found, but it is not a viable one.

Reproducible Demo

I dont have time right now to create a reproducible demo, because I cant share code from the one i found the bug in, but it's possible to reproduce with just using a simple <div> tag and seeing that the alignment is off.

bug css

Most helpful comment

@sanders-vag
a workaround would be to wrap all the html with a <p style="text-align: center"></p>:

<HTML {...otherProps} html={`<p style="text-align: center">${htmlContent}</p>`} />

Disclaimer: I only testet this with text and BRs and div as direct child of the centered P.

All 9 comments

I have the same problem!

Me too, any workaround available?

@sanders-vag
a workaround would be to wrap all the html with a <p style="text-align: center"></p>:

<HTML {...otherProps} html={`<p style="text-align: center">${htmlContent}</p>`} />

Disclaimer: I only testet this with text and BRs and div as direct child of the centered P.

Thanks @neXorianus! It worked like a charm!

@woba-ko I am implementing some tests to confirm the issue, and thus far the tests do confirm your assertions. But I am a bit surprised it only applies to Android, or did you meant that you could only test the issue on Android?

iOS correctly displays elements with text-align:center in the correct, hence centered, way.
on Android, the texts will be left aligned.

After some investigation, I identified two very distinct issues1:

  • CSS inline rules which are only translatable to RN TextStyles but are provided to HTML elements which are translated with View-based renderers get stripped, because RN does not support TextStyles on View elements. This is certainly something we should support, but it does add a layer of complexity since we must convey a context object containing Text-targeted rules and pass it through the rendering tree. Because it requires a sensible restructuring of the codebase, I will add this feature to the specs of the next major release. Example:

    <div style="text-align: center">foo bar</div>
    

    This issue happens on both Android and iOS.

  • A Text element provided with a style prop such as { textAlign: "center" } which has a Text ancestor will not center-align its content on Android. But it will on iOS. It looks like on Android, only the Text node closest to the root element is considered for text alignment. You can find a reproduction here: https://snack.expo.io/@jsamr/react-native-textalign. And you'll notice if you use Web output that the same issue will arise on the DOM.

    In RNRHTML, Text wrappers are sometimes added which is causing this bug, but I am not yet familiar enough with the codebase to identify in which circumstances exactly. I will investigate further on this, but I think a refactoring will also be necessary. I believe the right approach would be to never add text wrappers, and instead transfer all text wrapper properties to their Text children. I have yet to understand the implications of this.


1 I use the verb translate to denote HTML nodes to RN elements conversions, or CSS styles to RN styles conversions.

I have the same problem!

This issue has been fixed in the foundry release, available in alpha (see #430 for detailed information). The new transient render engine handles CSS properties inheritance, which allows a view-based renderer to have a text-align style and pass it to its children while avoiding injecting the corresponding react-native style (since textAlign cannot be applied to View elements).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

f-roland picture f-roland  路  3Comments

sayem314 picture sayem314  路  6Comments

Pradeet picture Pradeet  路  7Comments

HarrisKoffi picture HarrisKoffi  路  5Comments

xipgroc picture xipgroc  路  6Comments