Media queries and browser zoom - javascript

Long version
I've built a responsive webdesign for just two devices. Simplied example:
<link rel="stylesheet" media="screen and (min-width: 769px) and (max-width: 1199px)" href="tablet.css" />
<link rel="stylesheet" media="screen and (min-width: 1200px)" href="wide.css" />
This works as intended, on all major browsers, tablets (built with Bootstrap 3). The only issue that I have is that there are still people in this world that zoom their browser to 150+% in order to increase readability. This is not an issue, the page still works properly.
There is just one issue - the browser loads the "tablet" view on a 150+% zoomed in webbrowser. AFAIK this is normal behaviour, since there are less pixels available in the viewport, the appropriate media query loads the tablet.css file, just like when you resize the browser screen manually.
I'd like to counter this behaviour by forcing the desktop view, even when zoomed in. Can anyone point me in the right direction?
TLDR:
I've got a RWD scaling for tablet and desktop. Desktop browser zoom 150% = tablet view. How to prevent tablet view for desktop when zoomed in?
Note:
I'm using the viewport meta tag
No, this is not the issue explained here (http://blog.55minutes.com/2012/04/media-queries-and-browser-zoom/)
I've tried using media="screen and (min-device-width: 1200px) but that option renders me unable to 'test' the tablet-view on desktop since 'resizing' a screen simply doesn't work (device width = 1920px)

This will probably work. It's not something I would consider doing because if a user is always zoomed, they are used to things not looking the same and I don't think it's a big deal if your site is fluid and responsive. You will probably get FOUC.
First make an id for your style sheets:
<link id="responsivecss" href="responsive.css" rel="stylesheet" type="text/css" />
<link id="desktopcss" href="desktop.css" rel="stylesheet" type="text/css" />
Use a script to detect touch and no-touch. It's worked for me on Android, IOS, and Windows.
/* __________________ SUPPORTS TOUCH OR NOT __________________*/
/*! Detects touch support and adds appropriate classes to html and returns a JS object | Copyright (c) 2013 Izilla Partners Pty Ltd | http://www.izilla.com.au / Licensed under the MIT license | https://coderwall.com/p/egbgdw */
var supports = (function() {
var d = document.documentElement,
c = "ontouchstart" in window || navigator.msMaxTouchPoints;
if (c) {
d.className += " touch";
return {
touch: true
};
} else {
d.className += " no-touch";
return {
touch: false
};
}
})();
Then load or not load, this is an example, you can remove the second if, if not necessary:
$(document).ready(function () {
if ($('html').hasClass('touch')) {
$('#desktopcss').prop('disabled',true);
}
if ($('html').hasClass('no-touch')) {
$('#responsivecss').prop('disabled',true);
}
});
Quick demo, I haven't tested actual touch devices, but you can do a quick test by hard coding the class on the html element:
http://jsbin.com/gamir/1/edit

Related

Javascript and mobile browser width issues

My goal is to prevent the js from loading on an element when the browser width is less than 500px. Basically, I don't want it to load on most mobile devices.
var mq = window.matchMedia( "(max-width: 500px)" );
if (mq.matches) {
// Don't load function //
}
else {
// Load function //
}
It seems straightforward, and when I try it on my laptop, it works perfectly. At over 500px and the js loads. At under or equal to 500px, it doesn't load.
On my phone, however, my js media query doesn't work because the function loads. Someone suggested that it might have to do with my meta tag.
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"/>
I'm not sure what I'm doing wrong, but I can't seem to successfully relay the mobile browser width to javascript. Any help is greatly appreciated.
When it comes to mobile browsers you can get funky results by using max-width: 500px media queries, because of the high pixel densities in mobile screens. Your best bet is to use device media queries, e.g. max-device-width. So in your case it will look like this:
var mq = window.matchMedia("(max-device-width: 500px)");
if (mq.matches) {
// Don't load function //
}
else {
// Load function //
}

Browser width for mobile

I have a Nexus 5, and when I go to http://ryanve.com/lab/dimensions/, it tells me that my width 360. I understand that there is a difference between my phone's resolution and the width of my browser.
However, when I write a function to change at under 767:
function detectmob() {
if($(window).width() <= 767) {
return true;
}
else {
return false;
}
}
if (detectmob()){
}
else {
}
It doesn't work on my phone. If I resize my browser window width to be <= 767 on my laptop, the function works correctly. When I view it on my Nexus 5, it doesn't.
Could anyone help me write a function to target mobile devices using the browser width?
When you visit a website via a mobile browser it will assume that you're viewing a big desktop experience and that you want to see all of it, not just the top left corner. It will therefore set the viewport width at (in the case of iOS Safari) 980px, shoe-horning everything into its little display.
The Viewport Meta Tag
Enter the viewport meta tag, introduced by Apple, then adopted and developed further by others.
It looks like this:
<meta name="viewport" content="">
Within the content="" you can enter a load of comma delimited values, but we're going to to focus on the fundamental ones for now.
For example, if your mobile design is purposely laid out at 320px you can specify the viewport width:
<meta name="viewport" content="width=320">
http://webdesign.tutsplus.com/articles/quick-tip-dont-forget-the-viewport-meta-tag--webdesign-5972

Guidelines for resizing and adjusting for mobile devices using javascript

I have been having an issue with resizing web pages to fit on mobile devices using JavaScript. Is there a certain width that most programmers use to start changing the resize for mobile devices? Can anyone recommend any guidelines that I should or need to follow when working with mobile devices? I am now being instructed to make sure all web pages are "mobile friendly".
function adjustStyle() {
var width = 0;
// get the width.. more cross-browser issues
if (window.innerHeight) {
width = window.innerWidth;
} else if (document.documentElement && document.documentElement.clientHeight) {
width = document.documentElement.clientWidth;
} else if (document.body) {
width = document.body.clientWidth;
}
// now we should have it
if (width < 650) {
document.getElementById("myCSS").setAttribute("href", "css/narrow.css");
} else {
document.getElementById("myCSS").setAttribute("href", "css/main.css");
}
}
// now call it when the window is resized.
window.onresize = function () {
adjustStyle();
};
For starters, you shouldn't rely on Javascript to make your pages responsive to different resolutions or screens sizes, CSS can handle that for you using media-queries.
Javascript should be used in responsive design only under these circumstances:
You have an extreme design feature that is impossible to pull off correctly in CSS
You want to enhance your web page by adding in some interactions, animations or custom behaviors.
You have an experimental website where users are expecting something out of the ordinary
You are willing to warn your users if javascript is required to display/run your page properly.
It is best practice to only use javascript to enhance your page after you have written your responsive layouts in CSS, that way, your site is still functional if javascript is turned off in the browser.
"Progressive enhancement" is a popular technique for web developers who want to get the page looking nicely while assuming Javascript is turned off, so that users without javascript will still get a nice experience, then, progressive-enhancement in javascript means that the user can be ensured an even better experience if they have javascript turned on, because they might see some nice animations, and cool parallax scrolling, etc.
With that said, your question was directly asking about using javascript for responsive design, so from there, the advice is simple:
Use jQuery's bind() or resize()functions to listen for browser resize events:
$(window).resize(function() {
// handle layout here
// change widths, heights, positions, etc
});
$(window).bind("resize", function(){
// handle layout here
// change widths, heights, positions, etc
});
And from there, you can effect the width's height's and positions of your elements, or assign CSS properties to them, depending on your design.
As for good "breakpoints" (screen sizes to watch for in your responsive layouts), you can refer to this guide: Media Queries for Common Device Breakpoints.
I tend to start somewhere around here, and then tweak as I go:
Mobile: width: 320px - 750px
Tablets: width: > 750px - 1024px
Laptops/Desktops: width: > 1024px
And then I test on multiple devices, and make changes accordingly, your final design will dictate the final numbers you choose as your breakpoints.
Hope this helps.
I typically use a width of 600 to adjust for mobile devices.
Make sure to add this meta tag inside the <head> tag:
<meta name="viewport" content="width=device-width">
This should make the page render at a reasonable size.
Add this <style> tag inside the <head> tag:
<style>
img {
max-width: 100%;
}
</style>
I think this will make sure all images don't render any wider than the app's webview's viewport.
(If that doesn't work, try width: 100%; instead. That'll definitely make all images be as wide as the viewport, and therefore no wider.)
You can also try the #media tags in your css, they allow you to completely reprogram it depending on the resolution:
#media screen and (max-width: 600px) {
.button {
width:300px;
}
}
then for different resolutions above mobile
#media screen (min-width: 600px) and (max-width: 1200px) {
.button {
width:500px;
}
}
But you can always use jquery's
$(window).resize(...) which binds a callback for the resize event or triggers this event.
Bind a callback function, if the users resizes the browser window:
$(window).resize(function() {
alert('resize handler called');
});
If you want to call all listeners manually (without any parameters):
$(window).resize();

Target iPad3 but not iPad4

I'm try to add some css that will need to execute on iPad 3, but not iPad 4 or vice verse. I'm able to target both leaving the old version with:
#media
only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and ( min--moz-device-pixel-ratio: 2),
only screen and ( -o-min-device-pixel-ratio: 2/1),
only screen and ( min-device-pixel-ratio: 2),
only screen and ( min-resolution: 192dpi),
only screen and ( min-resolution: 2dppx) { }
but so far I can't find a difference to target between 3 and 4. Any css or JS solutions out there. Any help will be greatly appreciated
You can't get any difference by using media queries or user-agents:
Media queries are the same
User Agent contains only iPad word, not version. Other info in UA is about iOS or Safari browser. iPad3 has iOS6 be default, but in can be updated for new versions. Safari depends from iOS version, so system and browser information is imprecise.
So there is only javascript+iOS feature detecting like was with iPad and iPad2 difference in event.acceleration, but there is no different in features of iPad3 and iPad4.
So you can't detect iPad3 only. May be you post here the problem with iPad3 and we can help you to solve it?
BUT:
If you use WebView component, you can do it in it. You can detect in by systemInfo.machine string in Objective-C:
NSString *machineName = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
machineName for iPad3 are iPad3,1, iPad3,2 and iPad3,3. iPad4 are iPad3,4, iPad3,5 and iPad3,6 (don't ask why:)
And in WebView you can change your css file to iPad3.css by using WebResourceLoadDelegate for example.
Confirming that you can't get any difference by media queries or user-agents, I've found a difference between iPad3 and iPad4 using WebGL and js.
Using EXT_texture_filter_anisotropic and its extension object MAX_TEXTURE_MAX_ANISOTROPY_EXT you can return the maximum available anisotropy for a texture.
IPad3 returns 2, iPad4 returns 16
I guess this is due to their different GPU.
Demo
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Anisotropy</title>
</head>
<body>
<p style="font-size: 100px;" id="anisotropy_val"></p>
<canvas id="webGLCanvas" width="400" height="400">
</canvas>
</body>
<script>
function check_max_anisotropy() {
var canvas = document.getElementById("webGLCanvas");
var gl = canvas.getContext("experimental-webgl");
var ext = (
gl.getExtension('EXT_texture_filter_anisotropic') ||
gl.getExtension('MOZ_EXT_texture_filter_anisotropic') ||
gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic')
);
if (ext){
var max = gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
}
document.getElementById("anisotropy_val").innerHTML = max;
}
check_max_anisotropy();
</script>
</html>

Optional Javascript Execution based on Media Queries

I'm trying to figure out how I can optionally run a block of javascript based on the current device/media query. I'm using Twitter Bootstrap and have essentially two versions of media queries:
#media (min-width: 980px) { ... } <!-- Desktops -->
#media (max-width: 979px) { ... } <!-- Smaller screens/tablets/phones -->
I have a map that I generate, but am not showing it in the mobile/small screen version forb andwidth reasons. Yet, the javascript still executes in the background even though you can't see it on the mobile screen. So, I'm trying to find a way in javascript where I can do something like:
// Imaginary function
var screenType = getScreenType();
if(screenType == 1) {
// Load map
}
I've read about people setting CSS properties to specific values in their media queries and then trying to find that element in the DOM based on the CSS property, but there has got to be a better way. Any ideas?
The current accepted answer is not good enough, you should check window.matchMedia
You can detect viewport dimension changes, but you must calculate factors such as orientation and aspect ratios and there is no guarantee our calculation will match our browser assumptions when it applies media query rules.
I mean, you can calculate X, but your browser assumption can be Y.
So i think is better to use same browser rules, and window.matchMedia does it
var jmediaquery = window.matchMedia( "(min-width: 480px)" )
if (jmediaquery.matches) {
// window width is at least 480px
}
else {
// window width is less than 480px
}
You can even receive query notification using a listener
var jmediaquery = window.matchMedia("(orientation: portrait)");
jmediaquery.addListener(handleOrientationChange);
handleOrientationChange(jmediaquery);
function handleOrientationChange(jmediaquery) {
if (jmediaquery.matches) {
// orientation changed
}
}
If you no longer need to receive notifications about changes simply call removeListener()
jmediaquery.removeListener(handleOrientationChange);
You might find the Enquire.js library helpful:
http://wickynilliams.github.com/enquire.js/
CSS-Tricks article: http://css-tricks.com/enquire-js-media-query-callbacks-in-javascript/
How about using javascript for that?
<script type="text/javascript">
if (screen.width < 980) {
document.write('<link href="UrLowRes.css" type="text/css" rel="stylesheet"/>');
} else {
document.write('<link href="UrlHighRes.css" type="text/css" rel="stylesheet"/>');
}
</script>
You can also using a plugin called minwidth:
minwidth(940, function () {
//do whatever you need
});
But it only works when the page loads not when resizing..
http://edenspiekermann.com/en/blog/responsive-javascript-helpers

Categories