Why does a CSS border look different on Android? - android

I have a box with a border.
border: 1px solid #000;
I am using the following viewport setup:
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
The border seems to be 2 pixels on the top and right side.
What is the reason for this?
Additional: there are no other CSS rules other than a width and height.

The meta tag that targeted pixel-density specifically has been depreciated and now both Android and iPhone seem to be just using the one metatag:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
But, if you try to make a 1px border, it will be thicker and thinner on different sides depending on the mobile device's pixel density.
How some devices render '1px' with multiple pixels and it is not always pretty because they are using different pixel ratios (dpr) such as 1.5, 2 and 3. Sometimes, all 4 sides of a 1px border will not match.
This is some CSS to make 1px display properly on 2dpr iPhone by dividing 1px by half:
#media only screen and (-webkit-min-device-pixel-ratio: 2) {
div {
border-width: 0.5px;
}
And similar techniques are shown here:
http://n12v.com/css-retina-and-physical-pixels/
https://developer.android.com/guide/webapps/targeting.html

"Could you modify your answer to make it working for all devices, regardless the DPI? Would be super useful! – Basj"
i dont know how much this helpfull
here i added a custom function to get border size on almost all dpr
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Pixel Ratio</title>
<style>
.bord {
width: 300px;
height: 300px;
border: 10px solid #000;
}
</style>
</head>
<body>
<div class="bord"> </div>
<script>
dprof("bord");
function dprof(elmclass){
var z =document.getElementsByClassName(elmclass).length;
var dpr = window.devicePixelRatio;
for(i=0;i<z;i++){
document.getElementsByClassName(elmclass).item(i).classList.add("dpr-"+dpr);
var bw =getComputedStyle(document.getElementsByClassName(elmclass).item(i),null).getPropertyValue('border-width');
var nw =bw.replace("px","");
var nbw=nw/dpr;
console.log(nbw);
if(nbw!=0){
document.getElementsByClassName(elmclass).item(i).style.borderWidth=nbw+"px";
}
}
}
</script>
</body>
</html>

Unless you have a very good reason for it (doubtful), disabling user-zoom is a very bad idea. See user-scalable=no … Evil or Slightly Not Evil? for examples of why this is bad. It also gives some examples where user-scalable=no is perfectly acceptable.
for a 1.5 pixel-ratio, try
#media only screen and (-webkit-min-device-pixel-ratio: 1.5) {
div {
border-width: 0.75px;
}
}

Related

White space at bottom on mobile, not reproducible in Chrome simulator

I know there are various similar threads on this but none answer my question. Please look at this most simple HTML code.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html, body {
margin: 0;
height: 100%;
background: linear-gradient(to top, blue, white);
background-attachment: fixed;
}
</style>
</head>
<body>
</body>
</html>
Viewed in Chrome for PC (either in normal view or in mobile simulator view) it produces a gradient background that covers the whole screen. Viewed in Firefox mobile for Android or Chrome mobile, the website has a white space at the bottom the size of the address-bar. It either appears right away or it appears when you attempt to scroll the page. Why is it there and how do I get rid of it?
i had the same Problem till hours before.
Set body-height not 100vh, but 100%.
body,html{ padding: 0; margin: 0; height: 100%; } (No background input here!)
In your html document you have to put in a new image-Tag('<'img id="image"'>')
At the end in CSS:
#image{ height: 100vh; background-image: url(..); z-index:-1; background-size: cover; }
So i found out, that 100% is smaller than 100vh actually, what actually kills the white bar at the bottom on android browser while scrolling out the navibar.
Sorry for my broken english. Greetings from germany. xD

CSS 1px border in a Webview gives 2px border on some sides, when devicePixelRatio = 1.5

I'm loading a page in a Android app with a WebView (=embedded browser in app), with standard settings:
mywebView = (WebView) findViewById(R.id.activity_main_webview);
...
mywebView.loadUrl("http://example.com/test");
Everything works correctly except the following minor issue:
Problem: The 1-pixel-wide border is not displayed correctly: one or two of the four sides of the border are 2px instead of 1px. It looks like this:
I noticed that window.devicePixelRatio = 1.5 on my device
Here is the HTML code (I don't use a code snippet, because they are not runnable on mobile devices anyway):
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style type="text/css">
#test { display: inline-block; border: 1px solid #c4c4c4; padding: 9px; }
</style>
</head>
<body>
<a id="test">Test</a>
</body>
</html>
The solutions given in this question (I have put a bounty there, so I already tested the answers) don't work: border: 0.5px solid black; or border: 0.75px solid black; show no border at all, so this is not a duplicate. This is a specific question when devicePixelRatio = 1.5 (it behaves different than 1 or 2)
Live demo here, I cannot reproduce the problem in Chrome for Android, but only in a Android app using WebView and displaying the same page (strange, isn't WebView using the same rendering engine as Chrome?)
I just have a similar problem and it is fixed, I do not if this solution will help you or not:
It helped by give a margin to the div
.brand .col-8 {
padding-right:0;
margin-right:-1px;
}
.brand .col-4 {
border-left:1px solid #d8d8d8;
}

Why doesn't this page fit onto a screen properly?

I have made very basic page, here is the HTML code:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Test Page</title>
<style>
#Canvas {
width: 1400px;
background-color: #09F;
position: relative;
margin-left: auto;
margin-right: auto;
}
#SiteHeader {
width: 1200px;
background-color: #CCC;
height: 165px;
margin-right: auto;
margin-left: auto;
margin-top: 15px;
border: 5px solid #F0F;
}
</style>
</head>
<body>
<div id="Canvas">
<div id="SiteHeader"> Why does this not fit in the screen? </div>
</div>
</body>
</html>
Just a simple #Canvas div to hold the content, and then a #SiteHeader div with a border around it. Here is a link to it:
The problem: When this page is viewed in a browser such as IE 11 on my Windows 8 RT tablet, the page does not fit the screen. When I say fit I mean that it should appear zoomed out so that I can see the entire page. I have to scroll horizontally to see the entire page.
I tried to use <meta name="viewport" content="width=1400"/> which seems to work for Android but not IE in Windows 8 Metro app.
I want the full 1400px width to appear on the screen even if the resolution of the screen is not that wide. It just needs to load zoomed-out but for some reason this page doesn't. Please can anyone suggest why?
You need to use this way, so that whatever the page size is given, that won't be changed by the viewport.
<meta name="viewport" content="width=device-width, user-scalable=no">
But in this case, there will be scrollbars in the small devices. Try it out yourself.
Okay, I think I figured it out.
Although these other website do have wrapper divs which far exceed the width of most devices, the actual content is inside a div which is less than 1080px wide.
My Windows 8 tablet has a resolution of 1920x1200. So when I rotate to view in portrait mode (display width of 1200px), it appears as if the website has shrunk (or been zoomed out of) to fit, but its not. Its just the extra background detail in the wrapper div has been chopped off, but the content still fits in the portrait width of my device which is 1080px.
If my tablet had a lower native resolution say 1024x768, then even a 960px width website would get chopped off in portrait mode.
Finally, and maybe most importantly, any divs that provide a background must not have a width set that is not flexible. Basically, always set CSS attribute to max-width: 1200px; rather than width: 1200px. This means that on smaller screens it will collapse to the width of the inner content div.

Double-width borders on Android devices with a CSS pixel ratio of 1.5

Given a simple page (source below) that contains an element with a 1px border, it will render like this on Android compared to iOS:
As you can see, the Android border does not have a uniform width, sometimes being 1px and sometimes being 2px wide. As far as I've been able to test it, this only occurs on devices with a CSS pixel ratio of 1.5 (including the Android emulator), but not with a pixel ratio of 2 (including iOS). I believe that this problem is caused by subpixel-antialias and/or rounding issues, but I honestly have no idea how I'd go about fixing this.
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<style type="text/css">
div {
width: 100px;
text-align: center;
margin-left: 50%;
border: 1px solid magenta;
}
</style>
</head>
<body>
<div>Foobar</div>
</body>
</html>
For low DPI devices I found next workaround:
.wrapper {
background-color: red;
padding: 1px;
display: inline-block;
}
.inner_text {
padding: 5px;
background-color: #fff;
display: inline-block;
}
<div class="wrapper">
<span class="inner_text">Showing perfect one-sized border on low DPI devices</span>
</div>
for exactly low dpi devices should use media query for exceptions.
For example #media (max-resolution: 190dpi) or another condition
It looks little different from border 1px but so close and not bugged with random width

Android ignores maximum-scale when using fixed-width viewport meta-tag

I have a fixed-width web page (640 pixels wide). I would like this page to shrink to the width of a mobile device. However, if the device's native width is larger than 640 pixels, I do not want it stretched. Seems simple enough:
<meta name="viewport" content="width=640, maximum-scale=1.0" />
This works as expected in iPad/iPhone. However, on an Android tablet (ex. in landscape mode), the content gets scaled up to fit the display. In other words, Android is simply ignoring maximum-scale=1 . You can see an example page with the problem here. For the sake of completeness here is the source:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test Viewport</title>
<meta name="viewport" content="width=640, maximum-scale=1.0" />
<style>
div.bar {
position: absolute;
width: 636px;
height: 50px;
background-color: yellow;
border: 2px solid black;
left: 50%;
margin-left: -320px;
}
</style>
</head>
<body>
<div class="bar">
</div>
</body>
</html>
I've been doing a lot of researching and experimentation with the viewport meta-tag. I've read just about everything on the topic, but haven't seen this seemingly basic issue mentioned.
Two notes:
This is not a target-densitydpi issue
Setting the viewport width to device-width is not helpful in this case because the content width is fixed and larger than (for example) a phone's portrait device width. If I set width=device-width, the page will not automatically be scaled down to fit the phone..
Thanks much.
After more banging my head against a table, I have found a solution:
Unfortunately it seems that iOS and Android simply behave differently (Android is very clearly not doing what the spec says by ignoring maximum-scale). The solution is to specialize based on resolution using JavaScript:
If the screen width (see note below) is greater than or equal to the fixed page width (640 in my example), then set the viewport meta-tag's content width to the screen width
Else set the viewport meta-tag's content width to fixed page width (640)
Presto. Lame that it requires JavaScript specialization, but such is life.
Note that the Javascript screen.width on iPad/iPhone is incorrect if the device is landscape mode (the iPad still reports the portrait width instead of the landscape width, unlike Android which gets it right in this case!). Therefore, you'll need to check window.orientation on iPad/iPhone and use screen.height instead of screen.width if you are in landscape.
I'd rather use
width=640, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, target-densityDpi=device-dpi
Instead of just the Max scale property...
The target-densityDpi property si Android specific, maybe it can fix your problem.

Categories

Resources