The problem only appears on KitKat with the new WebView mechanism.
Basically I am loading 12 images, one after another in a row. I want the WebView to load all images on a row and auto zoom the webView to fir the entire row.
How it works prior android 4.4
the images are loaded on the row and the zoom is made to fit the entire row. The user can scroll in and out
How it works on 4.4
the images are wrapped, so I have the first image drawn and the next one is under it, not to its right
The html loads images like this:
<meta name="viewport" content="width=device-width, height=device-height, minimum-scale=0.3, user-scalable=yes, initial-scale=1"/>
<style type="text/css">
body {margin: 0; padding: 0; border: 0; float: left; white-space: nowrap;}
.Image .Tile-0-0 {background: url(tiles/tile_0_0.png) no-repeat; width: 128px; height: 128px; float: left;}
.....
and then
<body>
<div class="Image">
<div class="tile-0-0"></div>
<div class="tile-1-0"></div>
.......<br/>
Any ideas? My guess is that somehow I need to tell webview to fit the entire row, not wrap on the device's width.
How could I fix this ?
Android 4.4 (KitKat) has a completely different WebView (based on Chromium source) than previous Android versions. There is a migration guide that describes common problems you might experience.
In your case the first thing I'd check is whether the HTML renders correctly in Chrome.
If it does, try setting targetSdk to 19 in your manifest (this disables some quirks) and see if that helps.
If it doesn't it might be a change in how CSS is interpreted/layout is performed between the two WebView implementations. Try fiddling with your CSS and see if that helps. Using DevTools should make it simpler.
Another thing to look at is the viewport - see if the document.documentElement.clientWidth differs between the two versions. If it does then that's the reason it looks differently. If you're using wrap_contents height try using match_parent/a fixed value.
Related
I have a fixed footer with bottom: 0. It works fine except on android it is appearing below the screen. I have some other fixed elements that are also appearing off screen. For some reason I cant container them within the screen I've searched around and tried a view things but no joy. My guess is that if I change something in the viewport it will fix it. The image was taken from google chrome emulating the site on an S4 but the same problem persists on my actual phone also. The code for the footer should just make it sit at the bottom and it works fine in other browsers. I can change the value of bottom to around 26px then the whole footer becomes visible on the screen but that is not the fix I want. Any ideas?
.footer-fixed{
position: fixed;
bottom: 0;
z-index: 99;
width:100%;
background-color: #111;
height: 50px;
}
i've had this issue before,
but only on android versions lower then 4.4, so maybe you could tell me what android version you are working on,
try adding:
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, user-scalable=yes"/>
to your
<head></head>
on Android < 2.3 devices for elements that are fixed behave as "STATIC", (thats why your top element could be functioning normally, because its the first element and pushes the rest down)
Android 2.3 supports it but u need to disable viewport scaling as i think once written by bradfrost cant exactly remember, it was a while ago
if you experience flickering of the elment try adding
-webkit-backface-visibility: hidden;
to your css class, or even extend it with
-webkit-transform: translate3d(0,0,0); makes some devices run their hardware acceleration.
-webkit-perspective: 1000;
its solves the flickering, but the thing is on some android versions you only need to add the backface-visibility hidden and on some the other 2 rules (trial and error). i should go for the first one, (at first) because adding the translate 3d, will drain more battery
anyways if its just a website try the solution above,
if you are making a cordova app, try adding https://crosswalk-project.org/ which add their own webview to your cordova package solving all these browser quirks on android.
--
a sidenote
when a element has position fixed, its display will be set to block,
and you have width: 100% on your elment, so if you are not using box-sizing:border-box;
the element would have a width of 100% + padding + margin added to it,
i don't know the rest of your css, maybe you are setting margin or padding by a container class which is
(check the metrics of your element with chrome inspector)
If this is the case you could do 2 things
change display
width: 100% to auto;
or add: http://www.paulirish.com/2012/box-sizing-border-box-ftw/
box-sizing: -webkit-box-sizing: border-box;
or add normalize: https://necolas.github.io/normalize.css/ to your project, above your own css (link tag) within the head (Normalize.css makes browsers render all elements more consistently and in line with modern standards. It precisely targets only the styles that need normalizing.)
No one ever quite answered this similar question,
Blurry images on stock android browser
So I'm going to post my own version specific to my situation.
The problem is that position:fixed causes child image elements to be blurry in some android browsers. In my case, it causes the stock browser of Galaxy Note v1 running Android 4.0 to experience this issue. Others have said the same thing for some Galaxy S3. Here's my code:
Preview # http://jl.evermight.net/blurryposition/
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, maximum-scale=1.0,initial-scale=1.0, user-scalable=no" />
</head>
<body>
<div id="top-nav-container"
style="
display:block;
top:0px;
position:fixed;
width:100%; height:5.2rem;
">
<a style="background-image:url(logotest_big.jpg);
background-size:20%;
display:block;
width:500px;
height:200px;
"></a>
</div>
</body>
</html>
You'll notice that the OPTIX Testing logo is blurry at first. If you remove position:fixed from the #top-nav-container, then the logo is crisp and clear. So my question is, how do I keep both position:fixed and a crisp logo?
In my real website, the top navigation is supposed to stay fixed while you scroll through the site. I tried using position:absolute and using javascript to reposition the top navigation on scroll, but that caused a whole bunch of jumping/flickering effects. So if I can't use position:fixed or position:absolute to fix the top navigation to the top of a mobile web browser, what are my other options? How do other mobile websites achieve this result?
Additional Info:
I did some more experiments with the resizing image, changing view port, and changing the position:fixed/absolute and came to some interesting results. See below:
position:fixed no-background-size with-viewport - fuzzy
position:fixed no-background-size without-viewport - crisp
position:fixed background-size:20% with-viewport - fuzzy
position:fixed background-size:20% without-viewport - fuzzy
position:absolute no-background-size with-viewport - fuzzy
position:absolute no-background-size without-viewport - crisp
position:absolute background-size:20% with-viewport - crisp
position:absolute background-size:20% without-viewport - crisp
Here's how to read this chart:
first column states whether #top-nav-container is using position:fixed or position:absolute
second column states if i used background-size:20% or if i omitted it
third column states whether i included the <meta viewport> tag in the head
fourth column states whether the optix testing logo is fuzzy or crisp.
Looking at the results, you can see that the only time you get a crisp image with a container that has position:fixed is when an image has not been stretched or compressed via background-size or or with the view port. Also, the only time you get a fuzzy image with a container that has position:absolute is when an image has been stretched with background-size and with a viewport.
Using position: fixed is still a bad idea on mobile devices. The overwhelming majority of websites fall back to a static header for mobile views (ie. no floating navbar).
I experienced similar issues recently, as illustrated in this question.
A few resources for you:
Read this article on Quirksmode to learn about the problem: http://www.quirksmode.org/blog/archives/2010/12/the_fifth_posit.html
See which mobile browsers support position: fixed in this table: http://caniuse.com/#search=fixed
add inside top-nav-container.
<div id="top-nav-container"
style="
display:block;
top:0px;
position:fixed;
width:100%; height:5.2rem;
">
<a style="background-image:url(logotest_big.jpg);
background-size:20%;
display:block;
width:500px;
height:200px;
"></a>
</div>
I got this problem too when creating fixed action bar with div using background-image as icon. But when I add Text in that action bar, that background-image become crisp. So I just add as replacement for Text if I don't want any Text on my action bar.
Sorry for my bad English :D
Instead of user-scalable=no change it to user-scalable=0
try this:
img {
transform: scale(1) rotate(0) translate3d(0,0,0);
}
<div style="position:fixed;"><img/></div>
<div style="position:fixed;"></div><!--add it-->
add a "fixed" element follow the "fixed", just like up.
After looking all around for solutions, I am just tired of trying out every straw I find.
So, my situation is like this:
I have a scrollable div with floated images in it and I am using scrollLeft, offsetLeft and style.width to dynamically expand this div.
Now, while this is working great on iOS and PC, on Android (7") the scrollLeft value is scaled down nearly to 50%! However style.width value is not scaled down, like the other ones.
This would be the css for my items:
.slider-item {
margin: 0 13px 0 0;
width: 300px;
float: left;
height: inherit;
}
And my viewport:
<meta id="viewport" name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
My questions:
is there somewhere a complete guide to webview from the HTML/JS point of view? because most of the time I stumble on solutions, where it is necessary to adjust the android-app - i would like to avoid that.
how can I determine the adapted scale of my device using JavaScript or the correct style.width respectively the correct image position?
If someone could explain this to me, I would be so happy!
PS.: Just found an additional bug: When I have scrolled some elements to the left, so far, that I reached the empty area; then tap in the empty area, it actually opens a link of one of the elements, which is by now out of sight! But the point where I tap would fit to the actual position, where the element should be on a normal display.
I am quite lost with this o_O
Edit: I mistakenly had put the wronk variable here: it's the syle.width of my slider-items, which is wrong, not their offsetLeft.
Working with #media might be impossible, as my window.innerWidth is 1280px on android and 1024 on iOS. Both show an offsetWidth or width property for my slider-items of 300px - BUT Android scrollLeft shows 155px, when I already have scrolled away one whole picture, which should have been 300px wide - there's the problem.
have you tried playing with WebView initial scale? Like this: webView.setInitialScale(100);
So I've only experienced this issue on the Android browser so far. Basically my site works fine almost all the time (and I've not seen the problem yet on Dolphin, Opera or Skyfire) but occasionally when I reopen the Android browser from a bookmark on one of my phone's homescreens my site appears stretched horizontally, so now I only see the first 2/3 of the left hand side. Its' as though the browser just lost the CSS or the meta information while it was minimized. Here are my meta tags, and I'm using width 100% in my table styles.
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="keywords" content="Task, Tasks, Goal, Goals, Habit, Habits, Track, Tracking, Best Habit Tracker"/>
<meta name="description" content="Top Habit Tracker!"/>
<meta name="mobileoptimized" content="0"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
This issue only seems to happen when the bookmark is clicked after about 30 min. to reopen the stock Android browser. Then, it seems browser gets the page from its cache, but still runs window onload for ajax, so I'm thinking the combination of it using a browser-cached page with (maybe?) the javascript DOM manipulations from ajax on top is something that the Android stock browser uniquely has problems with, breaking my table width outside the viewport. Or maybe the DOM changes have nothing to do with it.
If the phone is switched off, then on, and the bookmarked clicked, the stock browser reloads the page from the server, then I don't get the problem. If the browser is minimized, and the bookmark re-clicked after just 2 minutes, no problem either because the browser just re-displays itself and the last page exactly as it was left, without doing anything.
I've been thinking of some kind of hack I could throw on top to force a reload from server in the case where the page is grabbed from brower cache, or I guesss I could try turning off browser caching, but I'm wondering about the implications of doing that on images, css, load time etc. Weighing up my options... thoughts welcome.
UPDATE: Well turning off browser caching may have reduced the incidence of this issue (not sure?) but definitely didn't cure it. I'm now thinking I may be having the same issue as described in this blog post:
http://www.gabrielweinberg.com/blog/2011/03/working-around-androids-screenwidth-bug.html
UPDATE: OK nothing I've tried so far has prevented this intermittent issue in my Android stock browser. I'm going to switch my regular use of my app to Dolphin for a while to see if the issue occurs in that browser. What I've tried so far is: using meta tags to disable browser caching (I think to some extent the Android browser ignores that anyway)... changing the table width (I may try that again in a different way)... Using the solution posted at comment 14 here (dynamically creating CSS link): https://code.google.com/p/android/issues/detail?id=11961#c14 and lastly I've tried appending Datetime ticks to the URL in an effort to alleviate caching, that hasn't worked either.
More useful info here: http://f055.tumblr.com/post/6364300769/viewport-bugs-in-android-browser
Not sure if this will help u - but this is what I did for my mobile apps
This is the only meta I use...
<meta content="initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" name="viewport">
<div class=general>
All Ur Content in here etc - or next div etc...
Below the margin-left: 1% and margin-right: 1% formats your div to your width
So if ur browser is upright or wide - it is always 1% border width and fits screen.
Don't use any table width=800 or anything - control it with the 1% margins
</div>
.general {
font-family: Verdana; font-size: 10pt; font-weight: normal;
position: relative;
background-color: #fafafa;
padding: 8px;
margin-top: 4px;
margin-left: 1%;
margin-right: 1%;
border: 1px solid #000;
border-radius:5px;
}
I'm trying to mimick desktop-style iframes in Android (Dolphin browser) with some succes. The trick used is to put an <iframe> with position:relative; inside a <div> with fixed dimensions and overflow:hidden;, then using jQuery Mobile (or rather just the vmouse events) to handle mouse events for scrolling.
All this works fine except for one thing; Even though the <iframe> is clipped, it's content stretches the browser to match size. This is mostly noticable in height.
Here's simplified example code in JSFiddle: http://jsfiddle.net/euKhG/
And here's the result to watch within the Android browser: http://jsfiddle.net/euKhG/embedded/result/ (only works in Android browser!).
Does anybody know how to fix this issue? I've seen iScroll and similar suggested elsewhere, but they seem to touch frames with a remote src like this.
try setting target-densitydpi in meta tag
<meta id="viewport" name="viewport" content="initial-scale=1, user-scalable=no, width=device-width, target-densitydpi=160dpi"/>
but you'll have to change all other css with respect to this as well
Mmmm, I think you missed something here. Right now your iFrame is getting cut off yes, but not due to you setting overflow:scroll, nor due to you setting a width/height property of the container frame; the cutoff that you are currently seeing is entirely arbitrary.
To prove this, add a background:#ff0000 to your container div, and you will see that it truly is not the div's width / height that is defining the cutoff region of your iframe but rather some 'default' iframe dimension properties: http://jsfiddle.net/kauUr/
My recommendation is, given you said your div is of fixed dimensions, set up your iframe with width/height properties of those same dimensions so that it matches. You can either do this using the width and height attributes, or more cleanly using css justas you have done for the container div. Once you give the iFrame the correct width / height, the cutoff should match what you expect and the browser shouldn't scroll to the size of the contents of the iframe, but rather to your specified dimensions. In fact, even if the div's dimensions aren't known ahead of time, you can use Javascript to acquire them and then correctly size the iFrame in runtime.
<div style="width: 400px; height: 400px; overflow: scroll; background:#ff0000">
<iframe style="width: 400px; height: 400px" src="http://doc.jsfiddle.net" frameborder="0" scrolling="no"></iframe>
</div>
And if that doesn't work, try slapping an overflow:none in the iframe style as well.