Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding CSS styling to React Native WebView

So I am a bit stumped on this ... I'm using a WebView in a portion of our app, the reason for the WebView is because we are pulling from an API endpoint that returns to us an HTML string. The font size and other things in this HTML string aren't styled for the purpose of using in a mobile app so we are trying to add some stylistic changes to it for better viewability. I've seen people add Style Tags at the top of the html file to add specific html styles to the element, and everything is generally working except the font size in the HTML of WebView renders differently every time I click into the screen that has the WebView contained in it.

Here is the current code (style + html + script):

let rawHTML = htmlStyle + this.props.itemDetails.body_html.replace("\n", "").replace(/("\/\/[c])\w/g, "\"https://cd").replace(/(width: 10.094%;)/g, "").replace(/(width: 84.906%;)/g, "") + heightScript

I have also console logged this string out in the debugger to make sure it's stitched well, and have even created and index.html and pasted in there the exact string, to make sure it's just showing up properly there.

Here is the style string:

let htmlStyle = `<style>
                        #height-calculator {
                          margin: 0;
                          padding: 0;
                        }
                        #height-calculator {
                            position: absolute;
                            top: 0;
                            left: 0;
                            right: 0;
                            margin: 0;
                            padding: 0;
                        }
                        body {
                          width:100%;
                        }
                        h2 {
                          font-size: 48px;
                        }
                        p {
                          font-size: 18px;
                        }
                        h3 {
                          font-size: 32px
                        }
                        img {
                          width:98%;
                        }
                        td {
                          display: block !important;
                          width: 95% !important;
                        }
                        img {
                          width:98%;
                        }
                        hr {
                          width: 98%;
                        }
                        ol li ol li ol li {
                          position: relative; right: 85px;
                        }
                        ul {
                          width: 98%,
                          margin-left: -25px;
                        }
                        li {
                          width: 98%;
                        }
                        .tabs {
                          display: none;
                        }
                        .tabs > li {
                          display: none;
                        }
                        .tabs-content {
                          padding: 0;
                          list-style-type: none;
                        }
                        tr {
                          display: flex;
                          flex-direction: column;
                        }
               </style>`

And finally here is the WebView:

<WebView
  javaScriptEnabled={true}
  onNavigationStateChange={this.onNavigationStateChange.bind(this)}
  scrollEnabled={false}
  source={{html: rawHTML}}
  style={{height: Number(this.state.height)}}
  domStorageEnabled={true}
  scalesPageToFit={true}
  decelerationRate="normal"
  javaScriptEnabledAndroid={true} />

Also, as I mentioned all the other styles applied are working, it's mainly just the font size that is super unpredictable.

Here is the view when I click it one time:

enter image description here

And then I don't change or exit the app, I just go back, and then click the same button to enter that same display and I get this sometimes (it sometimes takes multiple clicks ... it's very unpredictable):

enter image description here

I have a video of this as well, if you feel that would help this explanation. I'm trying to retell it the best I can haha.

Edit:

I think this might be a simulator only related issue? If anyone could speak some wisdom into that, that would be awesome still. I can't seem to reproduce this error on production build.

like image 419
Taylor King Avatar asked Mar 29 '17 18:03

Taylor King


People also ask

Does React Native use CSS for styling?

With React Native, you style your application using JavaScript. All of the core components accept a prop named style . The style names and values usually match how CSS works on the web, except names are written using camel casing, e.g. backgroundColor rather than background-color .

Can I use HTML and CSS in React Native?

When working with React Native, by default it does not use HTML and CSS as a web application. In fact, right out of the box, everything is automatically styled based on Flexbox. In this article, you will be introduced to how to apply styling to React Native applications.

How do I change the background color in React Native Webview?

No, you cannot change the background color of a webview, but you can use another view with your background color cover on your web view.


2 Answers

I recently experienced the same issue. It was only occurring for me on iOS, not Android.

The weirdest part is the inconsistency in replication. I couldn't find any pattern to when the WebView content would be sized differently. Identical HTML would result in font size that was sometimes normal, but other times very tiny.

My solution came from a (RN 0.47) WebView prop:

scalesPageToFit?: bool

Boolean that controls whether the web content is scaled to fit the view and enables the user to change the scale. The default value is true.

I tried setting scalesPageToFit to false, and voilà, the page stopped scaling down:

<WebView
  source={{ html: myHtml }}
  scalesPageToFit={false}
/>

The only problem is that this caused my content to be scaled larger than the WebView's container on Android. To fix this, I simply set the scalesPageToFit prop conditionally, based on platform:

<WebView
  source={{ html: myHtml }}
  scalesPageToFit={(Platform.OS === 'ios') ? false : true}
/>

Worked like a charm for me!

like image 88
djpo Avatar answered Oct 04 '22 15:10

djpo


I used react-native-render-html. The reason I choose this solution over the accepted answer is because I can style html tags using react native styles instead of injecting style declaration string before the actual content.

const htmlStyles = { p: {fontFamily: 'Lato'} }
const htmlContent = <H1>My Html</H1>;

<HTML containerStyle={ {margin: 16} }
                html={ htmlContent } 
                tagsStyles={ htmlStyles } />
like image 23
emil f. Avatar answered Oct 04 '22 14:10

emil f.