CSS position:fixed causes blurry images in Android Browsers - android

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.

Related

Linear gradient in Chrome on Android

This code works exactly as expected in every desktop browser (Chrome, Edge, Firefox, Safari) and also in Firefox on Android. I don't have an iOS device to test with - I'd be curious to know what happens on an iPhone.
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title>Background</title>
<style>
html {
height:100%;
background:linear-gradient(red, blue) no-repeat fixed;
}
.wrapper {
min-width:590px;
padding:20px;
}
.box {
height:250px;
width:550px;
background-color:green;
}
</style>
</head>
<body>
<div class='wrapper'><div class='box'></div></div>
<div class='wrapper'><div class='box'></div></div>
<div class='wrapper'><div class='box'></div></div>
</body>
</html>
Live demo: https://misterneutron.com/lgtest/
The "no-repeat" attribute isn't even necessary, but just makes this demo even more clear. In short, it provides a red-to-blue linear gradient background that fills the viewport, and stays put if you have to scroll vertically or horizontally to see all of the green boxes. Firefox on Android flickers a bit, but gets the correct result. But in Chrome on Android, the background linear gradient scrolls with the content, leaving a white background. Without the "no-repeat" attribute, it actually repeats the background, apparently ignoring the "fixed" attribute.
Not surprisingly, the same thing happens with a background image (https://misterneutron.com/bgtest/). Same page code, but replace the html styling with:
html {
height:100%;
background: url('aspectWide.jpg') no-repeat fixed center center;
background-size: cover;
}
I've tried all types of alternates - 100-percenting things like height and width on html and body, putting the background on the body rather than the html, and so on. Nothing seems to change the behavior. Does anyone know how to beat this browser bug, or do I just have to wait for some future release? I could do some browser-sniffing and eliminate the background if it's Chrome on Android, but ugh.
There are threads about similar issues, but most are several years old, and address much older browser versions. And not one of the suggested workarounds has succeeded.
Edit: Another data point. The problem is much less severe with a repeating background: https://misterneutron.com/bgtest2/. But the "fixed" attribute is still being ignored. Much easier to live with than the original problem, however!

Chrome android height/scroll issue with footers and the address bar

So here is an interesting situation I have come across.
You are on Chrome for android, when you scroll the body the address bar runs away and hides. Great!
Now you want to add a footer to your page that sticks to the bottom. You do the following:
html {
margin:0;
padding:0;
height:100%;
}
body {
margin:0;
padding:0;
height:100%;
}
#contentWrap {
margin:0;
padding:0;
padding-bottom:4em;
min-height:calc(100% - 4em);
position:relative;
}
#footer {
margin:0;
padding:0;
height:4em;
width:100%;
position:absolute;
bottom:0;
background:#262626;
}
<html>
<body>
<div id="contentWrap">
<div id="footer">
</div>
</div>
</body>
</html>
This works brilliantly, the footer will always stick to the bottom of the page regardless of content size or view-port scale.
However! Running this on a mobile design and testing in Chrome Android I found that setting the body to an explicit size, it will only scroll "content within" causing the address bar to stick around. Overflowing content is just set to default scroll in other words.
Noticing this I tried changing it to min-height so that it will always either be the size of the view-port if no content is available to fill it, or change height if there happens to be many lines of content.
Doing this however causes the contentWrap to base its height on the content rather than the parent element ie. <body>. So your footer now floats instead of sticking to the bottom.
I have played around with many combinations and cant seem to get what I want. Seems you have to live with either a sticky address bar OR a floating footer.
Please any ideas or thoughts on this would be appreciated.
Thanks but no that does not work in this situation.
Earlier today though whilst working on another project it hit me like a wet fish.
Remove dimensions from <html>.
Then add 100vh to your <body> instead of 100%
(making sure to only target mobile devices and not desktops)
Then it works perfectly! xD
Though Chrome is awesome imo. The little address hide on scroll has given me numerous headaches over the past few months.
When i make footers,
I code in css
.footerdiv{position:fixed; left:0; right:0; bottom:0; height:60px; z-index:777}
That does the trick.
Z-index keeps it above all the other elements. Position:fixed keeps it from moving as you scroll. and the left,right,bottom keep it sized perfectly.
Style as you wish.
Hope this helps.

Android KitKat webview width of the html page

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.

What CSS code do I use to get my webpage to fill the screen on a the iPhone or Android?

I have the HTML code below. I have set the body's width to 640px which is close to what the iPhone's resolution is. However, when I view the webpage on either an iPhone or an Android, it shows up just like it would in my web browser - only taking up part of the screen. The text is so small it's not usable.
What CSS code do I use so that the text stays normal in desktop browsers, but fills the screen on a mobile device? I read some things about using device-width properties but I can't get those to work either. What am I doing wrong?
Note
I'm not trying to get the red border to stretch all the way across the screen (eg: body:width100%). I just don't understand why the iPhone is not zooming into an area that is set to the same resolution it is supposed to have.
HTML Code:
<style>
body{ width:640px; border: 1px solid red; }
</style>
</head>
<body>
Hello World
</body>
</html>
Actual Output:
Desired Output:
Put this in your head tag:
<meta name="viewport" content="width=480">
To make the iPhone zoom in on the page, you can use the viewport meta tag.
You can set a scale of 1.0 to make Mobile Safari zoom in on your content exactly, no matter it's actual size.
Here's some documentation on different ways of setting the viewport: http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html
Have you tried body { width:100%; border: 1px solid red; } ?
You'll have to use media queries for this.
http://www.alistapart.com/articles/responsive-web-design/
Example: http://www.alistapart.com/d/responsive-web-design/ex/ex-site-FINAL.html (Resize the page)
A seemingly straight-forward tutorial: http://coding.smashingmagazine.com/2010/07/19/how-to-use-css3-media-queries-to-create-a-mobile-version-of-your-website/
If you're creating a webapp for iphone, you should really take a look at PhoneGap. If you're feeling a bit adventurous, it really is quite easy to use.

Incorrect width in Android webkit browser

I noticed a problem on Android's default browser, where 100% width may actually go past the edge of the screen. Here's a minimal test case:
<div class='separator' width=100% style='border: 2px;padding: 2px;border-style: solid;'> </div>
<div class='separator' width=100% style='border: 2px;padding: 2px;border-style: solid;'>New & improved div</div>
<div class='separator' width=100% style='border: 2px;padding: 2px;border-style: solid;'>another working one</div>
<div class='separator' width=100% style='border: 2px;padding: 2px;border-style: solid;'>another</div>
This works as expected on a desktop browser, but in Android webkit browser, the first div goes way off the screen, and doesn't change width when zooming in and out. The divs after it work correctly.
Update: I've tested this on 2.3, 3.0, 3.1, and a newly created 2.2 emulator, they all fail to size it correctly. It looks like other people have noticed this, see here
and here. Anyone know a good workaround for this bug?
Just add this meta tag inside your html head tag .I've checked it with android 2.1 browser and it works fine on zoom.
<meta name="viewport" content="width=device-width" />
In my WebView, I was able to fix the widths by turning off wide viewport.
webview.getSettings().setUseWideViewPort(false);
This disables horizontal scroll unless absolutely necessary, and div widths and zoom work as expected. Obviously this will only work with a custom WebView, maybe there is a more generic way to do this with something like <meta name="viewport" ...> ?
use
layout_width="fillparent"
:)

Categories

Resources