Is it possible to detect on my page, for example using Javascript, when user visit it using mobile device in portrait mode, and stop orientation changing when user rotate its phone to landscape? There is game on my page, optimized for portrait display only and I don't want it in landscape.
New API's are developing (and are currently available)!
screen.orientation.lock(); // webkit only
and
screen.lockOrientation("orientation");
Where "orientation" can be any of the following:
portrait-primary -
It represents the orientation of the screen when it is in its primary portrait mode. A screen is considered in its primary portrait mode if the device is held in its normal position and that position is in portrait, or if the normal position of the device is in landscape and the device held turned by 90° clockwise. The normal position is device dependant.
portrait-secondary -
It represents the orientation of the screen when it is in its secondary portrait mode. A screen is considered in its secondary portrait mode if the device is held 180° from its normal position and that position is in portrait, or if the normal position of the device is in landscape and the device held is turned by 90° anticlockwise. The normal position is device dependant.
landscape-primary -
It represents the orientation of the screen when it is in its primary landscape mode. A screen is considered in its primary landscape mode if the device is held in its normal position and that position is in landscape, or if the normal position of the device is in portrait and the device held is turned by 90° clockwise. The normal position is device dependant.
landscape-secondary -
It represents the orientation of the screen when it is in its secondary landscape mode. A screen is considered in its secondary landscape mode if the device held is 180° from its normal position and that position is in landscape, or if the normal position of the device is in portrait and the device held is turned by 90° anticlockwise. The normal position is device dependant.
portrait -
It represents both portrait-primary and portrait-secondary.
landscape -
It represents both landscape-primary and landscape-secondary.
default -
It represents either portrait-primary and landscape-primary depends on natural orientation of devices. For example, if the panel resolution is 1280800, default will make it landscape, if the resolution is 8001280, default will make it to portrait.
Mozilla recommends adding a lockOrientationUniversal to screen to make it more cross-browser compatible.
screen.lockOrientationUniversal = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation;
Go here for more info (deprecated API): https://developer.mozilla.org/en-US/docs/Web/API/Screen/lockOrientation
Modern API docs in MDN is here: https://developer.mozilla.org/en-US/docs/Web/API/ScreenOrientation/lock
In JavaScript-enabled browsers it should be easy to determine if the screen is in landscape or portrait mode and compensate using CSS. It may be helpful to give users the option to disable this or at least warn them that device rotation will not work properly.
Edit
The easiest way to detect the orientation of the browser is to check the width of the browser versus the height of the browser. This also has the advantage that you'll know if the game is being played on a device that is naturally oriented in landscape mode (as some mobile devices like the PSP are). This makes more sense than trying to disable device rotation.
Edit 2
Daz has shown how you can detect device orientation, but detecting orientation is only half of the solution. If want to reverse the automatic orientation change, you'll need to rotate everything either 90° or 270°/-90°, e.g.
$(window).bind('orientationchange resize', function(event){
if (event.orientation) {
if (event.orientation == 'landscape') {
if (window.rotation == 90) {
rotate(this, -90);
} else {
rotate(this, 90);
}
}
}
});
function rotate(el, degs) {
iedegs = degs/90;
if (iedegs < 0) iedegs += 4;
transform = 'rotate('+degs+'deg)';
iefilter = 'progid:DXImageTransform.Microsoft.BasicImage(rotation='+iedegs+')';
styles = {
transform: transform,
'-webkit-transform': transform,
'-moz-transform': transform,
'-o-transform': transform,
filter: iefilter,
'-ms-filter': iefilter
};
$(el).css(styles);
}
Note: if you want to rotate in IE by an arbitrary angle (for other purposes), you'll need to use matrix transform, e.g.
rads = degs * Math.PI / 180;
m11 = m22 = Math.cos(rads);
m21 = Math.sin(rads);
m12 = -m21;
iefilter = "progid:DXImageTransform.Microsoft.Matrix("
+ "M11 = " + m11 + ", "
+ "M12 = " + m12 + ", "
+ "M21 = " + m21 + ", "
+ "M22 = " + m22 + ", sizingMethod = 'auto expand')";
styles['filter'] = styles['-ms-filter'] = iefilter;
—or use CSS Sandpaper. Also, this applies the rotation style to the window object, which I've never actually tested and don't know if works or not. You may need to apply the style to a document element instead.
Anyway, I would still recommend simply displaying a message that asks the user to play the game in portrait mode.
seems weird that no one proposed the CSS media query solution:
#media screen and (orientation: portrait) {
...
}
and the option to use a specific style sheet:
<link rel="stylesheet" type="text/css" href="css/style_p.css" media="screen and (orientation: portrait)">
MDN:
https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Media_queries#orientation
Simple Javascript code to make mobile browser display either in portrait or landscape..
(Even though you have to enter html code twice in the two DIVs (one for each mode), arguably this will load faster than using javascript to change the stylesheet...
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Mobile Device</title>
<script type="text/javascript">
// Detect whether device supports orientationchange event, otherwise fall back to
// the resize event.
var supportsOrientationChange = "onorientationchange" in window,
orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";
window.addEventListener(orientationEvent, function() {
if(window.orientation==0)
{
document.getElementById('portrait').style.display = '';
document.getElementById('landscape').style.display = 'none';
}
else if(window.orientation==90)
{
document.getElementById('portrait').style.display = 'none';
document.getElementById('landscape').style.display = '';
}
}, false);
</script>
<meta name="HandheldFriendly" content="true" />
<meta name="viewport" content="width=device-width, height=device-height, user-scalable=no" />
</head>
<body>
<div id="portrait" style="width:100%;height:100%;font-size:20px;">Portrait</div>
<div id="landscape" style="width:100%;height:100%;font-size:20px;">Landscape</div>
<script type="text/javascript">
if(window.orientation==0)
{
document.getElementById('portrait').style.display = '';
document.getElementById('landscape').style.display = 'none';
}
else if(window.orientation==90)
{
document.getElementById('portrait').style.display = 'none';
document.getElementById('landscape').style.display = '';
}
</script>
</body>
</html>
Tested and works on Android HTC Sense and Apple iPad.
With the new CSS3 features, you could rotate the page the opposite orientation that they rotated. Sorry, no IE7- support. :(.
var rotate = 0 - window.orientation;
setAttribute("transform:rotate("+rotate+"deg);-ms-transform:rotate("+rotate+"deg);-webkit-transform:rotate("+rotate+"deg)", "style");
This solution worked for me, which just rotates the entire page 90 degrees when it's in landscape (effectively locking the screen in portrait). I couldn't go with some of the other options here, because I needed to support Safari.
#media screen and (min-width: 320px) and (max-width: 767px) and (orientation: landscape) {
html {
transform: rotate(-90deg);
transform-origin: left top;
width: 100vh;
overflow-x: hidden;
position: absolute;
top: 100%;
left: 0;
}
}
Found it here: https://css-tricks.com/snippets/css/orientation-lock/
You could use the screenSize.width and screenSize.height properties and detect when the width > height and then handle that situation, either by letting the user know or by adjusting your screen accordingly.
But the best solution is what #Doozer1979 says... Why would you override what the user prefers?
You can detect the orientation change, but I don't think you can prevent it.
https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html
http://articles.sitepoint.com/article/iphone-development-12-tips/2
#rotate-device {
width: 100%;
height: 100%;
position: fixed;
z-index: 9999;
top: 0;
left: 0;
background-color: #000;
background-image: url(/path to img/rotate.png);
background-size: 100px 100px;
background-position: center;
background-repeat: no-repeat;
display: none;
}
#media only screen and (max-device-width: 667px) and (min-device-width: 320px) and (orientation: landscape){
#rotate-device {
display: block;
}
}
<div id="rotate-device"></div>
Related
In Android, Settings > Accessibility > Font Size the user can set font size between "Small", "Default", "Large", "Largest". Among other things, this setting affects default font size of HTML content in WebViews.
I've developed my layouts to look well with the default font size. Setting font size to "Largest" causes text to get cut off in some places, a horizontal scrollbar appear on others etc. In these cases I can use an alternative layout (for example, stack things vertically instead of horizontally), but I'm not sure how to detect which layout to use.
Ideally, I would use CSS media queries. Something like:
#foo {
display: flex;
}
#media (min-width: 360px) {
#foo {
/* If at least 360px available, use a horizontal layout */
flex-direction: row;
}
}
Problem is, the 360px breakpoint isn't affected by the Font Size setting on the device (which makes sense). I've also tried other measurement units: rem, ch, cm – but none of them seemed to take into account device's font size.
I've thought about doing something like this on page load:
display a line of constant text (say, "0000000000") on the screen
measure it in JS
if the measured width / device width ratio is above some set constant, switch to the alternative layout
But this approach would add complexity, delay and repaints and flicker on page load.
Is there a way to take device font size in account in CSS (media queries or otherwise)?
Short Answer
No, you cannot do this just using CSS. However you can minimise impact using a method similar to the one you mentioned in your question (measuring font size and adjusting layout accordingly).
Long Answer
You cannot do this with just CSS, however it is possible to have a performant website without repaints and fall-back to your default styles for no JS.
There is one downside to this method, you do end up injecting a style sheet into the page which will affect first contentful paint times. However bear in mind that this is essentially the same as having a matching media query (so in reality, there is no difference between this and a media query other than it relies on JavaScript).
You can mitigate this by inlining the relevant styles but obviously that carries a page weight cost. You will have to decide which is the greater sin!
The solution is quite simple.
(1) Work out the user's font size using the method similar to the one you described.
(2) Load in conditional CSS that overrides the key layout options as you desire.
(2a) Alternatively add a class to the body and change the layout based on that from styles within existing style sheets or inlined in the document if above the fold.
1. Work out the user's font size
You can do this in vanilla JS right within the header of the page as an inline script so it does not delay anything (other than parsing the script) and it will still be performant.
Try the below example with you font size set to "medium" first, then set your font-size to "extra large" and run the script again. Your font size should show as 16px and 24px respectively.
var el = document.getElementById('foo');
var style = window.getComputedStyle(el, null).getPropertyValue('font-size');
var fontSize = style;
console.log(style)
<div id="foo">a</div>
We now have a font size that is relative to the user's scaling.
We can further improve this by simply dividing the resultant font size by 16 (default size) to get a %age scale.
var el = document.getElementById('foo');
var style = window.getComputedStyle(el, null).getPropertyValue('font-size');
var fontSize = style;
var fontSizePercentage = parseFloat(style) / 16 * 100;
console.log(style, fontSizePercentage + "%");
<div id="foo">a</div>
2. Load in conditional CSS
Now that we know if the font size has been scaled by the user we simply conditionally load CSS.
To do this we need a simple JavaScript check
//set to whatever criteria you need, if your site still works on "large" font size and only needs adjustment at "extra large" then use 124 etc.
if(fontSizePercentage > 100){
//add the CSS
}
In the below example I have 3 columns that turn into 3 rows to demonstrate how font size dictates which styles to apply.
Please note to simulate a dynamically added CSS file I added some inline CSS code that gets written to a style sheet, you would obviously just add a style sheet (I have included a function to do this and just commented out where that function is called).
var el = document.getElementById('foo');
var style = window.getComputedStyle(el, null).getPropertyValue('font-size');
var fontSize = style;
var fontSizePercentage = parseFloat(style) / 16 * 100;
el.remove();
console.log(fontSizePercentage);
//this is just to simulate adding CSS, you would obviously import a style sheet properly here. I have put the proper function further down.
var normal = `
.col3{
float: left;
width: 32%;
margin-right: 1%;
}
`
var bigger = `
.col3{
float: left;
width: 100%;
}
`
var styleSheet = document.createElement("style");
styleSheet.type = "text/css";
if(fontSizePercentage > 100){
styleSheet.innerText = bigger;
}else{
styleSheet.innerText = normal;
}
document.head.appendChild(styleSheet);
////actual style sheet code/////
function addCss(fileName) {
var head = document.head;
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = fileName;
head.appendChild(link);
}
if(fontSizePercentage > 100){
//addCss('url-to-large-font-size-layout');
}else{
//addCss('url-to-normal-font-size-layout');
}
<div id="foo">a</div>
<div class="col3">column</div>
<div class="col3">column</div>
<div class="col3">column</div>
You will see from the example we add the stylesheet dynamically, choosing between two style sheets in the example. In reality you would probably only need to do the check for the requirement to use the large fonts stylesheet as your standard font size will be covered by your main CSS.
pros
This method effectively is the same as a 'font size media query' and carries a tiny JavaScript overhead.
cons
If you are bothered by repaints then performance is obviously important to you, this method adds an additional request and can delay First Contentful Paint / Initial page rendering for "above the fold content".
Because of this I offer a second suggestion:
2a. Add a class to the body.
Use exactly the same method as above but instead of inserting a style sheet simply use the check for font size to add a class to the body on page load.
The simply include the styles within your current style sheets but with the additional body class as a qualifier.
var el = document.getElementById('foo');
var style = window.getComputedStyle(el, null).getPropertyValue('font-size');
var fontSize = style;
var fontSizePercentage = parseFloat(style) / 16 * 100;
el.remove();
var bod = document.getElementById('simulated-body');
if(fontSizePercentage > 100){
bod.classList.add('large-font-layout');
}
console.log(fontSizePercentage);
.col3{
float: left;
width: 32%;
margin-right: 1%;
}
.large-font-layout .col3{
float: left;
width: 100%;
}
<div id="simulated-body">
<div id="foo">a</div>
<div class="col3">column</div>
<div class="col3">column</div>
<div class="col3">column</div>
</div>
pros this doesn't add any extra requests, should not affect your page paint. Generally this option will be preferable to the first option as you should only need to override a handful of CSS classes so the added weight is negligible.
cons - adds extra weight to your CSS.
Conclusion
Somebody should add a "user font size" media query :-P
Seriously though I would go with the (2a) option I gave you and inline your critical CSS. If you are changing more than 100 classes in your CSS (and so CSS weight becomes a problem) then something is wrong with your design so the speed difference will be negligible. Couple that with the fact that the JS is less than 1kb and it will not affect your paints and it is a simple but effective solution to your problem.
Bonus info for option 2
As an additional thought you can combine option 2 with checking the screen width to really minimise the amount of data sent down the wire. However this then starts adding considerable complexity which is something you said you wanted to avoid. I have included it here for completeness.
function getFontSizePercentage(){
var el = document.getElementById('foo');
var style = window.getComputedStyle(el, null).getPropertyValue('font-size');
var fontSize = style;
var fontSizePercentage = parseFloat(style) / 16 * 100;
el.remove();
return fontSizePercentage;
}
function getPageWidth(){
return Math.max(
document.body.scrollWidth,
document.documentElement.scrollWidth,
document.body.offsetWidth,
document.documentElement.offsetWidth,
document.documentElement.clientWidth
);
}
function addCSS(fileName) {
var head = document.head;
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = fileName;
head.appendChild(link);
}
var fontSizePercentage = getFontSizePercentage();
var pageWidth = getPageWidth();
var cssSize = "1920";
switch(true) {
case (pageWidth < 1366):
cssSize = "1366";
break;
case (pageWidth < 728):
var cssSize = "728";
break;
default:
cssSize = "1920";
}
var cssPath = "styles/screen-width-" + cssSize + "-font-size-adjust";
if(fontSizePercentage > 100){
console.log("adding CSS for width: " + cssSize, cssPath);
addCSS(cssPath);
}else{
console.log("not adding CSS", cssPath);
}
<div id="foo">a</div>
you can use the VH (viewport height) or VW(viewport width) font-size measures and the font will resize based on % of device viewport for example:
1vh = 1% of viewport heigth
2vw = 2% of viewport width etc
If you are doing media selector you could as well use rem or px as font-size.
You will still have to add #media selector for different devices, keep in mind viewport is the actual size of a device screen, like 10inch screens will have a #media selector up to 1280px or bellow.
/* please use caniuse.com for browser compatibility table*/
h1 {
font-size: 2.5vw;
}
h2 {
font-size: 2vw;
}
p {
font-size: 12px;
}
#media only screen and (max-width:768px) {
h1 {
font-size: 5vw;
}
h2 {
font-size: 4vw;
}
p {
font-size: 18px;
}
}
<h1>text</h1>
<h2>text</h2>
<p>some normal font controled by media query</p>
Is there a way to take device font size in account in CSS (media queries or otherwise)?
Media queries are used to set font size based on device width, not the contrary.
The unit you might use will always be based on the device width, not on the font size (as this can't be already defined at this point).
What you can do is, instead of defining the width of your columns based on percentage or using px units, you can set them on the base font size.
For instance, instead of
.flex-col {
flex: 0 1 30%;
}
you may use
.flex-col {
flex: 0 1 20rem;
}
The real problem are not your media queries but the fact that your containers are not defined in a responsive way (with both fix width and height for instance) causing cut off and scrollbars.
We need to implement hover only for desktop but not to any other devices like (mobile and ipad).
#media (hover: hover),
#media (hover: none) and (pointer: coarse)
We have tried restricting using these media queries:
#media (hover: hover) and (pointer: coarse) {
.abc:hover {
i {
background-color: red;
}
}
}
I expect the output of Hover should not be observed in any of devices other than in desktop (mainly during swipe/ long press), but the actual output is it is breaking in few android devices like Samsung J8(Chrome version -77.0.3865.92, Android version-9).
What you can do is, this way the hover only works on screens atleast 1024px wide.
#media screen and (min-width: 1024px) {
// only put your hover in here
.abc:hover {
i {
background-color: red
}
}
}
I have an App/WebApp that runs on Android and IOS. I deploy it both as a WebApp and a native PhoneGap app on IOS and Android. I build the native apps with PhoneGap Build. The tablet UI is designed for an internal pixel width of 768 which works fine on iPad and iPad Mini. For Nexus (601px wide in portrait) I fake it by setting the viewport width to 768px and setting the scaling as:
var gViewportScale = (Math.min(window.screen.width, window.screen.height) / window.devicePixelRatio) / 768;
if (gViewportScale >= 1) {
document.getElementById("viewport").content
= "width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no";
} else {
document.getElementById("viewport").content
= "width=768, initial-scale=" + gViewportScale + ", minimum-scale=" + gViewportScale + ", maximum-scale=" + gViewportScale + ", user-scalable=yes";
}
This mimics the iPad Mini behavior. This worked fine up until several months ago. I think this may have broken when I upgraded to Android 4.4 with the change to Chromium. Now the active area for the Android PGB native App is wider than the display. The WebApp continues to display properly in Android Chrome (33.0.1750.136) as it did before (i.e. it fills the display width in portrait). Also works fine as a native App or WebApp in IOS.
I've tried several alternatives and all the current versions of PGB and near as I can tell the Android WebView is ignoring the viewport meta tag with PhoneGap but not on Chrome. It certainly seems like an Android bug that it works on one and not the other.
I've asked this question in the PhoneGap support community and so far no good answers. I thought I'd try here. Of course, I could have separate CSS for Nexus, but true scaling of widths and fonts would be better.
You need to set webView.getSettings().setUseWideViewPort(true); else WebView will ignore the meta tag
I have a workaround that doesn't fix the fact that the viewport tag is ignored, but it solves the original viewport scaling problem in a manner that's probably better than playing with the viewport tag.
Inspired by:
Dynamic viewport resizing - Phonegap ignores viewport
and monaca:
https://github.com/monaca/monaca.js
I used a fixed viewport tag content:
width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no
and then use zoom, which Android and Chrome apparently support:
/*
* Make sure that the device is scaled so that it is at least minWidth px in width
* in any orientation. This is done by setting the zoom appropriately.
* Right now, we only need this on Android, which supports zoom.
* Plan B is to use transforms with scale and transform-origin.
*/
function setupScale (minWidth) {
var viewWidth = Math.max(document.documentElement.clientWidth, window.innerWidth);
var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
var portWidth = Math.min(viewWidth, viewHeight);
var landWidth = Math.max(viewWidth, viewHeight);
var fixScale = function () {
if (Math.abs(window.orientation) != 90) {
// portrait
document.body.style.zoom = portWidth / minWidth;
} else if (landWidth < minWidth) {
// landscape, but < minWidth
document.body.style.zoom = landWidth / minWidth;
} else {
// landscape >= minWidth. Turn off zoom.
// This will make things "larger" in landscape.
document.body.style.zoom = 1;
}
};
if (gPortWidth >= minWidth) {
return; // device is greater than minWidth even in portrait.
}
fixScale(); // fix the current scale.
window.onorientationchange = fixScale; // and when orientation is changed
}
For my app, it lets me set the minimum width of the webpage as 768. Which is the same as the iPad (Mini and regular). On the Nexus 7 which is reports screen width of 601px, I can use the same CSS as iPad.
I just created a little plugin to fix this prob (by using setUseWideViewPort(true)): https://github.com/gitawego/cordova-viewport-fix, if you don't wanna modify directly in the source code, you can use this plugin.
In order to use viewport in webView you need to enable setUseWideViewport and setLoadWithOverviewMode
mWebView.getSettings().setUseWideViewPort(true);
mWebView.getSettings().setLoadWithOverviewMode(true);
Refer: Pixel perfect UI in the WebView
I'm trying to compute the viewport geometric center on a webpage, rendered with Tablet devices (iOS and Android), ie the actual CENTER of the viewport (what you see) according to current translation and current zoom level - don't want the center of the document itself, I want the center of the screen what I'm viewing.
The problem is that this calculation is does not take into account any kind of zoom (an then) translation.
On iOS, I've tried with some of these answers, on the question detecting pinch to zoom on iOS,
I was able to catch the event "OnZoom" but didn't get any value, though.
On Android, I can't even catch any event related to zoom. I'm aware of touchmove and touchstart events, but how can I distinguish then in order to get zoom (and zoom value)
I'm using jQuery 1.7.2 library.
I have made a demo page which is confirmed to work on iPhone iPad, Samsung Galaxy Tab 10. I have only attached the click event on a huge div, so tap on the screen after zooming to update the display.
The calculation is very simple, use screen.width/window.innerWidth to get the zoom level. screen.width will always be in device pixels and window.innerWidth is always in css pixels, which also take the zoom into account.
Further calculation is simple math:
// round the result down to avoid "half pixels" for odd zoom levels
Math.floor(window.scrollY + window.innerHeight/2);
Math.floor(window.scrollX + window.innerWidth/2);
To check whether the user is zooming, attach the listener to window.resize and window.scroll which will fire after orientationchange hiding the address bar and zooming.
Here's my demo JavaScript:
var dot = document.getElementById("dot");
document.getElementById("main").addEventListener("click", function(e) {
var zoom = screen.width / window.innerWidth;
alert("zoom: " + zoom + "\n" + "ScrollY: " + window.scrollY);
dot.style.top = Math.floor(window.scrollY + window.innerHeight/2 - 5) + "px";
dot.style.left = Math.floor(window.scrollX + window.innerWidth/2 - 5) + "px";
}, false);
Setting up a simple HTML page, I can get pretty close to center.
With the code below, I'm just checking the width and height of a fixed div, and then combining that with the document offset and some simple maths to figure out the center, and place a single black dot there. I can get it pretty close, but it varies on my iPhone 4S.
Haven't tried on Android devices.
I don't think this would work on iOS <= 4, as they don't support fixed-positioning.
<style>
#fixed{
position: fixed;
left: 0; right: 0; top: 0; bottom: 0;
background: orange; opacity: 0.25;
}
.black{
position: absolute;
top:0;left:0;
width: 1px; height: 1px;
background: black;
}
</style>
<body>
<div id="fixed"></div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
<script>
jQuery(function($){
setInterval(function(){
var top = ($("#fixed").height()/2) + $("#fixed").offset().top;
var left = ($("#fixed").width()/2) + $("#fixed").offset().left;
$("body").append('<div class="black" style="top: '+top+'px; left: '+left+'px;" />');
}, 1500)
});
</script>
</body>
I had a client request a page zoom detection method in javascript a couple years ago.
In my case, he wanted it to work on a facebook app. Through the iframe canvas/viewport.
I used Max and Min functions
function getDocHeight() {
var D = document;
return Math.max(
Math.max(D.body.scrollHeight, D.documentElement.scrollHeight),
Math.max(D.body.offsetHeight, D.documentElement.offsetHeight),
Math.max(D.body.clientHeight, D.documentElement.clientHeight)
);
}
function getDocWidth() {
var D = document;
return Math.max(
Math.max(D.body.scrollWidth, D.documentElement.scrollWidth),
Math.max(D.body.offsetWidth, D.documentElement.offsetWidth),
Math.max(D.body.clientWidth, D.documentElement.clientWidth)
);
}
function getMinHeight(h) {
return Math.min(viewport.currentHeight, getDocHeight(), h);
}
getMinWidth was similar, but I had to apply browser-based tweaks to it.
I created an object called viewport which stored the properties of a fixed position div, specifically currentHeight and currentWidth were the offsetHeight and offsetWidth of the div element.
I ended up initializing a window.intervalTimer to run checks on the state of that div, comparedTo the stored values within the viewport object.
-webkit-device-pixel-ratio query is supported by both iOS and Android but since iOS does not support target-densitydpi=device-dpi it leads to different results. For example:
#media screen and (-webkit-device-pixel-ratio: 2) {
body { font-size: 2em; }
}
will make font look good on Galaxy Nexus, but on iPhone 4 it will be too big.
Is there a way to emulate target-densitydpi=device-dpi on iOS without JavaScript or to disable -webkit-device-pixel-ratio on iOS and leave its users with blurry images as a fallback?
#media (-webkit-min-device-pixel-ratio: 2), /* Retina on Webkit */
(min-resolution: 192dpi) /* Everyone else */ {
...
}
from this great article I incidentally read today:
http://www.w3.org/blog/CSS/2012/06/14/unprefix-webkit-device-pixel-ratio/