Adding CSS styling to React Native WebView - css

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

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!

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

Related

Basic CSS styles not applying

I cannot figure out how to get some basic CSS styles to apply to my blog. I'm trying to customize my blog summary page. I want the "read more" button centered and for the picture to show correctly. For some reason the picture keeps moving and it cuts it half off. I've tried multiple things to different classes and nothing works. It was originally on the left with the text to the right of the thumbnail and I'm moving the picture above the text if that means anything.
I've tried text align center for the button in multiple divs and it doesn't budge. Can anyone help? I can only adjust CSS not HTML on my Squarespace site, and the limited styles they give you doesn't allow me to adjust any of this. I'm not a coder, I just kinda understand it enough, so any help is appreciated.
Here is the page: https://www.themodernrenovator.com/blog
Here is custom CSS I added to make the button a circle, but can't get it to center:
text-align: center;
display: table;
width: 100px;
border-radius: 30px;
padding: 12px !important;
background-color: #f0ede9;
margin: auto;
}
.view-list article .excerpt-thumb {
width: 100%;
position: inherit;
}
.view-list article .excerpt-thumb .intrinsic .content {
position: inherit;
padding-bottom: 0px;
}
.intrinsic {
padding: 0px !important;
}
.entry-title {
text-align: center;
}
.article-dateline {
text-align: center;
}
article .post span.inline-action {
display: inline-block;
text-align: center;
}
.article-meta {
display: none;
}
I'd recommend centering the "READ MORE" button using the following CSS, inserted via the CSS Editor:
article .post span.inline-action {
display: inline-block;
text-align: center;
}
The "cut off" image problem, on the other hand, should not be corrected with CSS because it is an issue with Squarespace's ImageLoader function. To correct it, add the following via global Footer code injection. If code injection is not available to you, insert the code via a Markdown block in the footer of your website.
<script>
// Fix Squarespace ImageLoader Bug.
function fixImages() {
var images = document.querySelectorAll('img[data-src]');
var i = images.length;
while (i--) {
ImageLoader.load(images[i], {load: true});
}
}
fixImages();
window.Squarespace.onInitialize(Y, function() {
fixImages();
});
</script>
Your images are cut off because you have a top: value that's currently set to -300px. I can't tell where it's being affected just by looking at this, but somewhere in your styling you have the child img of your excerpt-image getting a top value being set.
To center your 'read more' link: .inline-read-more { margin: auto; }

Having trouble editing colors on a certain page on my wordpress site

I'm trying to edit the colors of my user profile page on my site www.wastelandgamers.com/user-profile I would like for the fields tat are blue to be white instead and the text in those fields to be black instead of white.
I am able to change them when I use the developer tools through Google Chrome and get the desired look, however, I am not able to find the HTML doc that I need to change in order to get the look I want. I have searched through nearly all of the relevant site files using file manager through cPanel with no luck.
Here are a screen captures of before and after the color change using developer tools.
Before code change:
After code change:
Code I need to change (.entry-content towards bottom)
.tml-profile {
max-width: 100%;
}
.tml-profile .tml-form-table {
border-collapse: collapse;
}
.tml-profile .tml-form-table th,
.tml-profile .tml-form-table td {
display: block;
vertical-align: middle;
width: auto;
}
.tml-profile .screen-reader-text,
.tml-profile .screen-reader-text span {
height: 1px;
left: -1000em;
overflow: hidden;
position: absolute;
width: 1px;
}
.tml-profile .wp-pwd {
text-align: right;
}
.tml-profile .wp-pwd .dashicons {
font-size: 1em;
line-height: 1;
height: 1em;
width: 1em;
vertical-align: middle;
}
.tml-profile #pass-strength-result {
margin: 0.5em 0;
}
.hidden,
.no-js .hide-if-no-js,
.js .hide-if-js {
display: none;
}
#media screen and (min-width: 768px) {
.tml-profile .tml-submit-wrap input {
width: auto;
}
}
.entry-content tr th, .entry-content thead th {
color: #cbcbcb;
background-color: #fff;
}
I am using the Parabola theme for my site and Theme my login for the profile page.
If anyone knows why I'm unable to find the file I need to edit or of another way to make the change I would really appreciate the help! If you need any more information let me know.
I'm not a fan of WordPress themes, but some of them do allow for custom CSS. Google found me this:
we have created a special input field right in theme’s settings page.
You’ll find it by going to Appearance > Theme Settings, then expanding
the Miscellaneous Section by clicking on it. The Custom CSS field is a
bit further down.
You should see this: https://www.cryoutcreations.eu/wp-content/uploads/2012/11/themesettings-customcssjs.png
In this area (indicated by the blue box), you will want to PRECISELY recreate the code you have circled above (http://i.stack.imgur.com/00cxb.png) EXCEPT for changing the #colour to your desired colour.

AngularJS Single page app: google maps reloading weirdness

Hi I am trying to build a angular single page app for mobile that uses a map on one page. It also should include a sticky footer, and is based on bootstrap. The sticky footer css interferes with the css needed to get the map to take up all of the remaining screen space, so I add a class='map' to the html element to override certain css elements (see below).
Everything works nicely until I go to the map page, leave it and then return to the map page. In this instance the map is not working correctly at all. It is hard to describe, so please try the plnkr.
I have found CSS that works for the map reloading, but then that breaks something else in the site. It is driving me crazy trying to combine the two models, hence my appeal for help.
Update: I have now found that resizing the screen rectifies the rendering issues, until you leave and return to the map. Of course a mobile use cannot change their screen size, but this may help find a solution.
html {
position: relative;
min-height: 100%;
}
html.map {
height: 100%
}
body {
/* Margin bottom by footer height */
margin-bottom: 60px;
}
.map body {
/* For Google map */
height: 100%;
margin-bottom: 0;
padding-bottom: 60px;
padding-top: 60px
}
footer {
position: absolute;
bottom: 0;
width: 100%;
/* Set the fixed height of the footer here */
height: 60px;
background-color: #f5f5f5;
}
header {
width: 100%;
background-color: #ccc;
height: 60px;
top: 0;
}
.map header {
position: absolute;
}
UPDATE
I implemented a solution similar to yours, which I found in this blog article. Essentially, you have to trigger a resize event in order to have the map repainted correctly when it goes from hidden to visible.
But I put my code into a directive instead of a controller (doesn't bloat controller and decorates the element it affects), instead of adding a watcher it runs only after the directive/element is linked (more performant), and it doesn't require you to re-enter your coordinates in order to refresh:
.directive('autoRefresh', function($timeout){
return {
restrict: 'A',
link: function(scope, elem, attrs){
$timeout(function(){
var center = scope.map.getCenter();
google.maps.event.trigger(scope.map, "resize");
scope.map.setCenter(center);
});
}
}
})
Updated Plunker
OK, so what I was missing was to trigger the resize event. This now works perfectly in my plunker but not yet in my more complex actual code. Nearly there!
restosApp.controller('mapCtrl', function($scope) {
$scope.$watch('map', function() {
google.maps.event.trigger($scope.map, 'resize');
var ll = new google.maps.LatLng(52.374, 4.899);
$scope.map.setCenter(ll);
});
});

Hiding Google Translate bar

I have the following code:
<div style="" class="skiptranslate">
<iframe frameborder="0" style="visibility:visible"
src="javascript:''"
class="goog-te-banner-frame skiptranslate"
id=":2.container"></iframe>
</div>
I need to hide it but if I only hide the goog-te-banner-frame using:
.goog-te-banner-frame {
display:none !important
}
It still throws my header down. If I use this:
.skiptranslate {
display:none !important
}
It also hides the language selection dropdown because it shares the same class.
I'd like to hide the skiptranslate div that CONTAINS the goog-te-banner-frame.
How do I do that?
Edit:
This is actual code to "create" the translate div above:
<div id="google_translate_element"></div>
<script type="text/javascript">
function googleTranslateElementInit() {
new google.translate.TranslateElement({pageLanguage: 'en',
layout: google.translate.TranslateElement.InlineLayout.SIMPLE,
autoDisplay: false,
includedLanguages: ''}, 'google_translate_element');}
</script>
<script type="text/javascript" src="http://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
Ok, this works for some reason:
.goog-te-banner-frame.skiptranslate {
display: none !important;
}
body {
top: 0px !important;
}
The selected answer is wrong!
I know this is an old question, but for anyone coming across this problem in the future, the easiest way:
body > .skiptranslate {
display: none;
}
Since the iframes are dynamically added directly to the body, you can simply select only direct descendants and nothing deeper.
This works for me:
.goog-te-banner-frame.skiptranslate {
display: none !important;
}
body {
top: 0px !important;
}
Why don't you just add an id to the skiptranslate div that holds the goog-te-banner-frame? <div id="something" class="skiptranslate" style=""> will then allow you to style div#something { display: none !important; }
Try to add another class, say .myClass {display: none;}, append to skiptranslate, like class="skiptranslate myClass"
EDIT:
Another solution:
You can also wrap the google translate code with another div, say <div id="google-wrapper">... google translate code...</div> and then style the wrapper with display: none;
OR
See this fiddle: http://jsfiddle.net/SryPD/
I found this to work the best for me. I send the Google Translate "origninal text" tooltip to z-index: -1000. So it is still in the page, but out of sight.
// Force hiding of "original text" popup for menus, etc. (very annoying)
jQuery(selector).bind(
"mouseenter mouseleave",
function (event) {
if (event.type === 'mouseenter') { google_trans_tt.css('z-index', -1000); }
else { google_trans_tt.css('z-index', 1000); }
}
);
October 2022: None of the above answers worked in my case.
I made it work by simply changing the z-index: of my website's menus, after I found the z-index: of the google translate's iframe (using of course the Developers Tools).
It works for me.
.goog-te-gadget img{
display:none !important;
}
body > .skiptranslate {
display: none;
}
body {
top: 0px !important;
}

CSS minimized mode in Opera: positioning in speed dial extension

I'm trying to display a scrolling list inside a speed dial box but have a problem with the positioning
I want to know when the list object is too big to fit the box, but as far as I know, there's no way of getting the size of the box in pixels
how can I get the minimized mode to show exactly what it's seen in the normal mode but fitting the box?
this is the CSS I'm using right now
* {
margin: 0;
padding: 0;
}
html {
height: 100%;
}
body {
background: #eee;
color: #444;
display: table;
height: 100%;
width: 100%;
}
output {
position:absolute;
width: 100%;
white-space:nowrap;
font-family: monospace;
}
it works fine if I open the file in a tab, but in the speed dial it's displayed zoomed in
Opera's guide uses this query:
#media screen and (view-mode: minimized) { }
which controls the way it's displayed in the speed dial, I think. but I don't know what to put in there
UPDATE
well, I ended up creating an element and assigning a bottom value of 0
like this:
var bottom = document.createElement('div');
bottom.className= "ylimit";
document.body.appendChild(bottom);
and in CSS:
div.ylimit{
position:absolute;
bottom:0px;
}
then whenever I want to check or compare the height, I use bottom.offsetHeight

Resources