Support for target-densitydpi is removed from WebKit - google-chrome

According to this https://bugs.webkit.org/show_bug.cgi?id=88047 WebKit dropped the support for target-densitydpi from viewport params. Unfortunately, the bug description states neither the motivation for the change, nor the workaround.
Certain web-pages that wanted to prevent scaling on mobile devices had the following declaration of the viewport:
<meta name="viewport" content="width=device-width,
initial-scale=1.0, maximum-scale=1.0,
user-scalable=no, target-densitydpi=device-dpi"/>
Now this code outputs an error in Chrome (tested with 21.0.1180.49 beta-m). Please advice what is the supposed way to make a web-page without the error messages and retain the same behavior as before with target-densitydpi=device-dpi"

I achieved the same thing on the latest Chrome for Android using this jQuery:
<meta content='user-scalable=no, initial-scale=1, width=device-width' id='viewport' name='viewport'>
var viewPortScale = 1 / window.devicePixelRatio;
$('#viewport').attr('content', 'user-scalable=no, initial-scale='+viewPortScale+', width=device-width');
This sets the initial-scale viewport meta tag setting to the correct scale for 1 CSS Pixel == 1 Device Pixel.
You can't use 'width='+screen.width because screen.width doesn't return the physical pixel dimensions. I tried using http://responsejs.com/labs/dimensions/ on my Nexus 7 in Chrome and all the numbers are viewport pixels.

The webkit-dev mailing list thread http://lists.webkit.org/pipermail/webkit-dev/2012-May/020847.html contains a discussion (or at least the background) of the feature removal.
In short, WebKit had a few means of scaling the page when rendered on a device, and this was highly confusing (even more so given that each platform relied on its own approach to this.)
UPDATE:
According to a comment on the said thread by Adam Barth, the mentioned patch author,
There's some concern that target-densitydpi is used by some apps that
are bundled with Android, but folks appear willing to deprecate the
feature and to migrate those apps to using other mechanisms, such as
responsive images and CSS device units.
As you can see, responsive images and CSS device units appear to be the recommended "workarounds" for what the target-densitydpi attribute provided. Also, another comment on the same thread mentioned the fact that even with this attribute in place, web developers would have to reimplement the same page in another way, for browser environments that do not support the attribute.
I believe the recently introduced subpixel layout will become another means of mitigating the attribute removal issue.
UPDATE 2
This blog post suggests an alternative way to laying out your page for Android Chrome. There is NO workaround that will automagically let you "retain the same behavior" of your pages. You just have to re-architecture them a bit.

I'm not sure, but maybe it's possible to emulate target-densitydpi by setting "width" in viewport metatag to be equal to screen width in "physical" pixels. Unfortunately, AFAIK, there is no 100% way to get device pixel width, but something like
<meta name="viewport" id="metaViewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<script>
if(navigator.userAgent.toLowerCase().indexOf('android') > -1)
document.getElementById('metaViewport').setAttribute('content', 'width='+screen.width+', initial-scale=1.0, maximum-scale=1.0, user-scalable=no');
</script>
should work on most Androids (James Pearce: First, Understand Your Screen).

Have you tried adding minimum-scale? Unfortunately, I don't have an android phone, so I can't test it for you.
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/>

Related

Prevent zoom in ios and android browser

Trying to find a way to prevent user to be able to zoom in a web page in latest ios and android.
I tried:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=0, shrink-to-fit=no">
...also:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=0">
...and:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
But it is still zoomable
Any others solutions ?
Thanks
This actually depends on the version of the browser you are using ,with each browser version having its own html code for restricting zooming.
If you use android 2.2 or below It is not supported at all
Android 2.3.x/3.x: By setting user-scalable=no you disable the scaling of the viewport meta tag yourself as well. This is probably why your width option is having no effect. To allow the browser to scale your content, you need to set user-scalable=yes, then to disable zoom you can set the min and max scale to the same value so it cannot shrink or grow. Toy with the initial scale until your site fits snugly.
Android 4.x: Same rule apply as 2.3.x except the min and max scales are not honored anymore and if you use user-scalable=yes the user can always zoom, setting it to 'no' means your own scale is ignored, this is the issue I'm facing now that drew me to this question... You cannot seem to disable zoom and scale at the same time in 4.x.
iOS/Safari (4.x/5.x tested): Scales work as expected, you can disable scaling with user-scalable=0 (keywords yes/no don't work in 4.x). iOS/Safari also has no concept of target-densitydpi so you should leave that out to avoid errors. You don't need min and max since you can switch off zooming in the expected manner. Only use width or you'll run into the iOS orientation bug
Chrome: Scales work as expected like they do in iOS, min and max are honored and you can switch off zooming by using user-scalable=no.
Conclusion: You can use some fairly simple JS to set the content accordingly after some basic browser/device detection. I know this type of detection is frowned upon but in this case it's almost unavoidable because each vendor has gone and done their own thing! Hope this helps people fighting the viewport, and if anyone has a solution for disabling zooming in Android 4.x WITHOUT the use of the viewport, please let me know.
<meta name="viewport" content="initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,width=device-width,height=device-height,target-densitydpi=device-dpi,user-scalable=yes" />
Android 4.x Chrome browser (which I think is pre-installed in most countries): You can make sure the user cannot zoom and the page is fullscreen. The downside: you have to make sure the content has a fixed width. I haven't tested this on lower Android versions. To do this see the example:
<meta name="viewport" content="width=620, user-scalable=no" />
iOS/Safari 8 Beta 4: There was a meta tag minimal-ui which worked fine in ios 7 versions ,however it has now been removed by Apple in this release.

Do browsers add "initial-scale=1.0" automatically?

I read this article https://css-tricks.com/snippets/html/responsive-meta-tag/ and followed tips by W3Schools, but I'm still confused with initial-scale=1.0.
I don't see the difference between this:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
and this:
<meta name="viewport" content="width=device-width">
I tested these code snippets in many browsers, and I cannot determine which one I need to use. If I omit initial-scale=1.0 will browsers somehow add it for me? It looks they will.
The "initial-scale=1.0" part sets the initial zoom level when the page is first loaded by the browser. "width=device-width" sets the width of the page to follow the screen-width of the device, depending on what they are using.
Here is a good link to read up on it:
https://www.w3schools.com/css/css_rwd_viewport.asp
"On high dpi screens, pages with initial-scale=1 will effectively be zoomed by browsers. Their text will be smooth and crisp, but their bitmap images will probably not take advantage of the full screen resolution. To get sharper images on these screens, web developers may want to design images – or whole layouts – at a higher scale than their final size and then scale them down using CSS or viewport properties. This is consistent with the CSS 2.1 specification, which says:" - MDN ,
https://developer.mozilla.org/en/docs/Mozilla/Mobile/Viewport_meta_tag
I did use initial-scale=1, but I noticed that removing it - against recommendations on CSS Tricks and by the authors of UIkit (v2) - gave me a perfect, as-expected, initial scaling on page load using Chrome on Android and with the Silk browser on a Kindle. Including initial-scale=1 meant the pages were loading at some semi-random zoom level, which looked amateurish. Edge, Chrome and Firefox desktop browsers are fine, but I haven't tested more widely on mobile devices yet.
For Android, I'm leaving initial-scale=1 off and I'll need a very good reason to put it back on again.
<meta name='viewport' content='width=device-width'>
CSS tricks actually uses the above on its own (very fine) site
Just use initial-scale=1.0
You would see the difference when viewing your website on different mobile devices.
For example the page being a way larger width of the screen and you have a horizontal scrollbar. You may think use overflow-x: hidden but no just set the initial scale to 1 for all devices in the head
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

Meta viewport tag seems to be ignored completely or has no effect

I have put this tag in the head of a webpage:
<meta name="viewport" content="width=device-width,initial-scale=0.47,maximum-scale=1">
For some reason, it simply seems to be ignored on my iPhone, even adding user-scalable=no has no effect. I have tried many values of width, initial-scale etc... nothing seems to have any effect.
Does anyone know what might be causing this? I can see clearly in the source that it is there in the header.
My iPhone is on iOS7.
Edit: The problem is still happening on iOS6 with the xcode ios simulator, so I don't think it is due to iOS7.
It is working! On your page you are using:
<meta content="width=640, initial-scale=0.47, maximum-scale=1.0, user-scalable=1" name="viewport">
When I open the page on my phone (ios7 iphone5) I see exactly the right result.
Are you 100% sure you really tried putting the following in your code?
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
It doesn't get ignored.
UPDATE1
I just saw that in your code it seems you are using my second viewport but i gets changed probably by javascript to the 640px viewport. Thats maybe the reason why for you it feels like it gets ignored. Because during runtime the viewport gets changed...
UPDATE2
Ok found the problem.
function updateWidth(){
viewport = document.querySelector("meta[name=viewport]");
if (window.orientation == 90 || window.orientation == -90) {
viewport.setAttribute('content', 'width=1401, initial-scale=0.34, maximum-scale=1.0, user-scalable=1');
}
else {
viewport.setAttribute('content', 'width=640, initial-scale=0.47, maximum-scale=1.0, user-scalable=1');
}
}
Your page is calling this function which overrides your viewport. Did you know about that function?
I know this is a hella old question now but it was the first result in Google when I had this issue so thought I'd update in regards to iOS 10.
It seems Apple now completely overrides the user-scalable=no in iOS 10 in order to improve accessibility
See: Thomas Fuchs' Twitter Post
You should try, as a workaround, the following code:
html {
zoom: .8;
}
Viewport width is different in many devices. iOS has 320, android has 360 in portrait mode. Landscape mode - it depends on which device you have, you will get a different pixel value.
The best way to make website optimized for mobile device is to set width=device-width. If you don't set initial-scale=1.0 - iOs will zoom in (enlarge) screen when changing device rotation.
This is the meta tag you need.
<meta name="viewport" content="width=device-width, initial-scale=1.0">
And if you wanted to disable the zoom feature, set user-scalable=no
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
Do not hard code width property as it will set same width for portrait and landscape modes - which is very unpleasing user experience.
Best documented: https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html
About iOs 7
Moreover I would say - dont worry about iOS7 as of now. It has so many bugs. Read here: http://www.sencha.com/blog/the-html5-scorecard-the-good-the-bad-and-the-ugly-in-ios7/
It seems that ios7 is not recognising the meta tag properly.
Here are the links which may help you.
webapp not scaling properly in iOS 7
http://www.mobilexweb.com/blog/safari-ios7-html5-problems-apis-review
Use below code.
<meta name="viewport" content="width=320, initial-scale=1, user-scalable=yes">
It works well in many of mine project.

What is the purpose of the viewport meta tag?

I am designing a mobile website and I first tried just to use a regular html page with a h1 tag. It looks very tiny so I searched and found out that I need to add these lines:
<meta name="viewport" content="width=device-width" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=yes" />
After trying several web pages to understand it, I still am confused. Is the viewport an additional device-width that on for example iPhone is 960px? Even though the iPhone 4 is only 640px so it scales it down to emulate that size? So in order to prevent it from thinking the viewport is 960px it says that it is equal to the size of the screen?
If this is the case, does other browswers/devices such as Android running devices have different widths (other than 960px)?
Per the jquery mobile documentation, there is a bug for iOS with this:
There is a minor issue in iOS that doesn't properly set the width when changing orientations with these viewport settings, but
this will hopefully be fixed a a future release. You can set other
viewport values to disable zooming if required since this is part of
your page content, not the library.
They recommend the follow line:
<meta name="viewport" content="width=device-width, initial-scale=1">
You also don't need the user-scalable either, the above line won't disable user zoom.

HTML5 Boilerplate, X-UA-Compatible and Windows Phone 7

i am having an issue with most of my new sites which use H5BP when viewed from Windows Phone 7 (or 7.5). The problem is that this HTML tag in the site's source
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
which should actually support different mobile devices, prevents the user of a mobile device (in our case Windows Phone 7 or greater user) to zoom in on the text (and the site itself).
Using this tag the mobile browser will adjust the size of the site according to the mobile viewport (i.e. mobile screen width and height). However, the problem is, when the user tries to zoom in on the text using the zoom-in gesture, the zooming doesn't work. It tries to zoom in but quickly returns to the initial width.
Has anyone else noticed this problem and if so, what is the solution?
You may want to test adding user-scalable=yes to see how Windows Phone handles the tag.
Although the tag is supported by almost all mobile browsers it isn't a standard tag (originated on the iPhone) so the implementation may differ. I find that Safari has the best documentation on the tag and as such I sourced it below.
This tag should be worth testing:
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
Source: Safari Documentation.
Additional resource: IE Mobile Viewport via Windows Phone Team.
I don't have a windows phone to test but perhaps adding the user-scalable=yes may help on windows mobile.
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">