media query, browser width issue on mobile - media-queries

This is my grid setup for media query. But, it shows its in 980px on my mobile.
#import "grid/grid";
$display_320: 'only screen and (max-width: 479px)'; $display_480:
'only screen and (min-width: 480px) and (max-width: 767px)';
$display_768: 'only screen and (min-width: 768px) and (max-width:
985px)'; $display_1024: 'only screen and (min-width: 986px)';
#media #{$display_320} { #import "grid/grid_320"; } #media
#{$display_480} { #import "grid/grid_480"; } #media #{$display_768} { #import "grid/grid_768"; } #media #{$display_1024} { #import
"grid/grid_1024"; }
My mobile phone is suppose to be 320px, but it says 980px. Do I have to do anything in my html?
Here is my code : http://jsfiddle.net/m38Gw/

> <meta content='width=device-width, initial-scale=1.0,
> maximum-scale=1.0, user-scalable=0' name='viewport' />
>
>
> <meta name="viewport" content="width=device-width" />
this solved my problem. Thanks

What's Going On
A lot of mobile browsers will provide fake information about their window width. This started with the iPhone because the pixel density was (is) so high compared to traditional computer monitors.
To give a more current example, the Galaxy S4 has a screen resolution of 1920x1080 pixels. That is the exact same as my 27" monitor. Media Queries, without resolution spoofing by mobile browsers, would be utterly useless here, because there is no difference in terms of real pixels.
To combat this, we have the viewport. This is the "fake" resolution of the mobile device, normally much smaller than the true resolution. Through the viewport we can retain use of media queries.
As tv4free stated, we have a tool to control the viewport, in the form of meta elements. One potential issue with his code though, is the maximum-scale. This will fix the viewport and not allow any scaling. Personally, I don't think that is an a problem is your media queries are properly designed. However, many people consider it to be a bad idea. If you leave out maximum-scale=1.0; user-scalable=0;, you will make the page load correctly each time, but allow the user to zoom in and out.
Code
Set the resolution, allow zoom:
<meta name="viewport" content="width=device-width; initial-scale=1.0;">
Set the resolution, don't allow zoom:
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"
More information:
http://www.quirksmode.org/mobile/viewports.html
http://www.quirksmode.org/mobile/viewports2.html

Related

IE 10 on WP8 ignores media queries?

I'm working on a site that uses media queries. I can see in my desktop browser that they are working correctly, but when I navigate to the site on my WP8 device, no CSS is loaded. I've created a very simple HTML page to replicate the problem and show what solution I tried, but couldn't get to work.
Here is the entire code:
<html>
<head>
<title>WP8 Test</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<style type="text/css">
#-webkit-viewport{width:device-width}
#-moz-viewport{width:device-width}
#-ms-viewport{width:device-width}
#-o-viewport{width:device-width}
#viewport{width:device-width}
#media screen and (min-width: 1024px) {
body {
background-color: red;
}
}
#media screen and (min-width: 768px) and (max-width: 1024px) {
body {
background-color: blue;
}
}
#media screen and (min-width: 480px) and (max-width: 768px) {
body {
background-color: green;
}
}
#media screen and (max-width: 480px) {
body {
background-color: yellow;
}
}
</style>
<script type="text/javascript">
if (navigator.userAgent.match(/IEMobile\/7\.0/)) {
var msViewportStyle = document.createElement("style");
msViewportStyle.appendChild(
document.createTextNode(
"#-ms-viewport{width:auto!important}"
)
);
document.getElementsByTagName("head")[0].
appendChild(msViewportStyle);
}
</script>
</head>
<body>
text
</body>
</html>
As you can see, it is very simple, there are 4 different "breakpoints" where the body's background color will change for different screen widths. After noticing how it doesn't work in IE on my WP8 device (a Lumia 822), I began googling the issue, and it seems to be a pretty well known issue. So the solution I found, and tried, came from here:
http://timkadlec.com/2013/01/windows-phone-8-and-device-width/
It seems pretty straightforward, in that I add the five lines to the top of my CSS:
#-webkit-viewport{width:device-width}
#-moz-viewport{width:device-width}
#-ms-viewport{width:device-width}
#-o-viewport{width:device-width}
#viewport{width:device-width}
And then add some JS to detect the IE Mobile browser from the UA. I have two issues with that:
First - When I alert my user agent string, I get the following from my WP8 device:
Mozilla/4.0 (compatible; MSIE 7.0;Windows Phone OS 7.0; Trident/3.1;IEMobile/7.0;NOKIA; Lumia 822
According to the article above, and this article, it should be IEMobile/10.0 instead. Any ideas on why mine is different? This appears to be the Windows Phone 7 user agent string. Why would my WP8 device show that?
Because of that difference, I had to change the JS to match 7.0 instead of 10, otherwise the if condition would never be met.
So, even still, with my code above, nothing happens, and my screen loads white on my WP8 device. Can anyone see what I'm doing wrong?
UPDATE:
It appears the JS was throwing an error:
Unexpected call to method or property access
So I found a solution for that, here:
if (navigator.userAgent.match(/IEMobile\/7\.0/)) {
var s = document.createElement("style");
s.setAttribute('type', 'text/css');
var cssText = "#-ms-viewport{width:auto!important}";
if(s.styleSheet) { // IE does it this way
s.styleSheet.cssText = cssText
} else { // everyone else does it this way
s.appendChild(document.createTextNode(cssText));
}
document.getElementsByTagName("head")[0].appendChild(s);
}
But, even now that the code executes successfully, my media queries are still ignored and I still see a white page load. Any ideas?
UPDATE 2:
I found another article, here (scroll to bottom), that says as of the GDR3 update (which I have, through the dev program):
Great news! Microsoft have fixed the viewport issue in WP8 Update 3
(GDR3).
Using device-width in a CSS #-ms-viewport rule now correctly renders
pages at the device-width, instead of the resolution width.
So, again I tried removing the Javascript, and adding only this to the top of my CSS:
#-ms-viewport{
width:device-width
}
But again, no CSS loads.
UPDATE 3:
It appears my User Agent may be correct. When I navigate to whatsmyuseragent.com on my WP8 device, it shows the correct UA. Maybe it has something to do with it being a local IIS 8.0 site when it reports the incorrect one? If that's the case am I not able to test my site locally from my Windows Phone? Has anyone ever done this?
It looks like you've sorted it now with bootstrap, but it's possible the site kicked in to EmulateIE7 (for compatibility) for some reason. It seems Lumia can also pick up on this for example if you have the <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> tag and of course media queries are not supported on IE7.

How do I 'scale' the UI to a readable size

When I display my app on a device, the fonts, icons and buttons are unusably small. This is especially true on a tablet.
How can I easily scale up all of of my UI components?
Make sure the following meta tag is included in your app html file:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
If you still feel that the buttons and text are to small (which the should be a personal preference) you could always try changing the css. Add a new rule like this:
body {
font-size: 140% !important; //I believe 114% is default
}
Hope it helps.

Background size not working in Opera Mini despite Modernizr thinking it should

I am using Modernizr to detect whether browsers support the CSS3 property background-size for a mobile site I'm building.
I'm testing the site in the Opera Mini 6 Simulator on the official Opera website, and Modernizr detects that the browser supports background-size and adds the class 'backgroundsize' to the <html> element accordingly.
However when I then use the background-size property in my CSS it is not supported.
Here's the head:
<script src="modernizr.js" type="text/javascript"></script>
<style>
body {
background:url('background.gif') no-repeat 0 0 #FFF;
}
.backgroundsize body {
-o-background-size: 100% auto;
background-size: 100% auto;
}
</style>
And the body content
<p>Content</p>
<script>
if (Modernizr.backgroundsize == true) {alert("Background size is supported");}
</script>
I am expecting the single background image to be stretched across the full width of the browser, instead it repeats; the page can be seen here - http://so.ajcw.com/mobile.htm
I guess one of five things has happened - does anyone know the reason and can offer a solution?
Modernizr does not work properly and has given a false positive
Opera Mini 6 incorrectly tells Modernizr it supports background-size when it doen't
The simulator is not an accurate emulation and the real Opera Mini does support background-size
I have written my code incorrectly
Or something else?
background-size is not supported in Opera Mini
I wrote this as a quick work around:
var isOperaMini = (navigator.userAgent.indexOf('Opera Mini') > -1);
if(isOperaMini) {
var root = document.documentElement;
root.className += " opera-mini";
}
It add's a class "opera-mini" to the html element. Therefore you can target Opera Mini. An example below:
.icon {
background-image: url("icon-social.svg");
background-size: 32px;
}
html.opera-mini .icon,
html.no-svg .icon {
background-image: url("icon-social.png");
}
See more at: http://anthonydillon.com/blog/#sthash.VUV1hIy2.dpuf
It seems things have changed. For my Opera Mini 7.5 on Android.
Modernizr.backgroundsize == true;
And it responds correctly to percentage values as well as to cover and contain.
#anthony's answer doesn't work as it's not resetting / removing the background-size property for Opera Mini. The correct way to do this is:
.class {
-o-background-size:cover;
-background-size:cover;
}
x:-o-prefocus, .class {
-o-background-size:;
background-size:;
}
The x:-o-prefocus targets just Opera browsers.

iPhone Safari does not auto scale back down on portrait->landscape->portrait

I have a very simple HTML page with this META tag for the iPhone:
<meta name="viewport" content="height=device-height,width=device-width,initial-scale=1.0,user-scalable=no" />
Using the iPhone Safari, when the page loads in portrait mode it looks fine and the width fits the screen.
When I rotate the iPhone to landscape mode the web page is auto resized to fit the landscape width. Good, this is what I want.
But when I rotate back from landscape, the page is not resized back to fit the portrait width like it was before. It remains in the landscape width.
I want the iPhone to set it back to the right width automatically, just like it did for the landscape mode.
I don't think this should involve orientation listeners because it is all done automatically and I don't have any special styling for the different modes.
Why doesn't the iPhone resize the web page back in portrait mode?
How do I fix this?
UPDATE
I managed to get the iPhone to auto resize down but with a strange phenomenon of doing it only after an even number of rotations... Very very strange.
I use this META tag:
<meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
Here's what I have to do to get it auto resized:
1. On load in portrait -> looks good.
2. Rotate to landscape -> resized to fit screen.
3. Rotate back to portrait -> no resize back.
4. Rotate to landscape -> still in size for landscape.
5. Rotate to portrait -> resized down to fit portrait screen.
Can someone explain this behavior??
I still want to know how to fix this and appreciate any assistance.
Thanks!
Tom.
This has to be a bug in iOS 4 Safari. Here's what my behavior was with the following meta tags (the second tag is to make it full screen):
<meta name="viewport" content="user-scalable=no, width=device-width"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
Page would scale correctly when going from portrait to landscape until I used the pop up keyboard to enter a value in a field - then it would stop scaling. Which would mean if I used the keyboard in landscape it would be too large when I went to portrait, or vice versa.
Switching using the following meta tags fixed it... Thanks to the other answers on this page.
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
I had the same problem on my 3GS 3.1.3, even though I couldn't get it to ever become the right size again after landscape mode. But when I removed "height=device-height" the page scaled down correctly every time. So my meta looks like this:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
I'd like to be able to use the height attribute to lock the height, but it seems like they don't mix too well.
You need to put one more thing minimum-scale=1.0 so it would like:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0" />
I'm using ExtJs (sencha touch), it seems Good
Ext.setup({
tabletStartupScreen: 'images/tablet_startup_768x1004.png',
phoneStartupScreen: 'images/phone_startup_320x460.png',
tabletIcon: 'images/tablet_icon_72x72.png',
phoneIcon: 'images/phone_icon_72x72.png',
icon: 'images/icon_72x72.png',
statusBarStyle: 'black',
glossOnIcon: true,
fullscreen: true,
onReady: function() {
var viewport = null;
var metas = document.getElementsByTagName('meta');
for(var i = 0, length = metas.length; i < length; ++i){
var meta = metas[i];
// already Extjs addedMetaTags
if(meta.name == 'viewport'){
viewport = Ext.get(meta);
break;
}
}
if(null == viewport){
viewport = Ext.get(document.createElement('meta'));
}
if(window.navigator.standalone){
// IMPORTANT!!! not set to height=device-height when iphone standalone mode was ignored "scale" settings
viewport.set({
name: 'viewport',
content: 'width=device-width, initial-scale=0.1, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'
});
} else {
// IMPORTANT!!! set to height=device-height when !standalone mode; behav window.innerHeight = fullscreen size
viewport.set({
name: 'viewport',
content: 'height=device-height, width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'
});
}
}
});
other devices compatible with ...
var watcher = {
handlers: [],
dimentions: {width:0, height: 0},
fullscreenize: false,
orientLandscape: function (){
return 90 === Math.abs(window.orientation);
},
orientPortrait: function (){
return !this.orientLandscape();
},
width: function (){
return this.dimentions.width;
},
height: function (){
return this.dimentions.height;
},
changeDimentions: function (evt){
var self = this;
(function (){
if(self.fullscreenize){
window.scrollTo(0, 1);
}
self.dimentions = Ext.Element.getViewSize();
self.fireOnchange();
}).defer(100);
},
init: function (){
if('onorientationchange' in window){
Event.observe(window, 'orientationchange', this.changeDimentions.bind(this));
} else {
Event.observe(window, 'resize', this.changeDimentions.bind(this));
}
Event.observe(window, 'load', this.changeDimentions.bind(this));
},
fullScreen: function (){
this.fullscreenize = true;
var self = this;
document.observe('dom:loaded', function (){
(function (){
window.scrollTo(0, 1);
self.changeDimentions();
}).defer(100);
});
},
fireOnchange: function(){
var self = this;
self.handlers.each(function (handler){
handler.apply(null, [self]);
});
},
onchange: function (handler){
this.handlers.push(handler);
}
};
watcher.init();
watcher.fullScreen();
aComponent = Ext.extend(Ext.Component, {
initComponent: function (){
watcher.onchange(this.fullscreen.bind(this));
},
fullscreen: function (){
var height = watcher.height();
var width = watcher.width();
this.menu.setHeight(40);
this.mainPanel.onResize(height - 40, width);
}
});
I also ran into the 'not scaling back when I went back to portrait' problem.
I got it working with
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.6, user-scalable=no" />
for basic scaling back and forth, on 3G with iOS 4, as I change orientation.
I originally used "minimum-scale=1.0", got it to work when I replaced it with "initial-scale=1.0", after I saw the suggestions here.
try this
<meta name="viewport" content="width=1024" />
Just set the viewport directive to...
<meta name="viewport" content="height=device-height, width=device-width, minimum-scale=1.0, user-scalable=yes|no" />
...no need to use JavaScript and you can still allow the user to scale the page should they wish.
Are you using XHTML rather than HTML?
Try this, ensuring you close your first meta tag correctly.
<meta name="viewport" content ="user-scalable=no, width=device-width"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
This is a bug in Safari on iOS 5 and lower (A.K.A. Safari Viewport Scaling Bug).
Try to avoid fix with meta viewport tags that disables the zoom gesture; instead, use this JavaScript fix:
https://gist.github.com/901295
More info about this bug: http://webdesignerwall.com/tutorials/iphone-safari-viewport-scaling-bug
I had the same problem with my iPhone 5. The answer was incredibly simple.
<meta name="viewport" content="width=device-width" />
This properly displays the page in either view, all the time, and offers scalability.
We faced the same issue in JQuery Mobile 1.3.0 also, we used the below and it worked
in css
body { /* IOS page orientation change resize issue*/
-webkit-text-size-adjust: none ;
}
and if still the header/footer does not resizes correctly (optional)
$(window).resize(function() {
$("div[data-role=header]").width($(window).width());
$("div[data-role=footer]").width($(window).width());
});

stop background of iphone webapp from responding to swipes

I'm making a mobile version of my website, and trying to make it feel as native as possible on the iphone. However, any background areas of the page respond to swiping gestures such that you can shift the page partway off the screen. Specifically, if the user touches and swipes left, for example, the content shifts off the edge of the screen and one can see a gray background 'behind' the page. How can this be prevented? I'd like to have the page itself be 320x480 with scroll-swiping disabled (except on list elements that I choose).
I have added the following meta tags to the top of the page:
<meta name="viewport" content="width=320; height=480; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
I've also tried the following as the event handler for the touchstart, touchmove, and touchend events of the body element:
function cancelTouchEvent(e) {
if (!e) var e = window.event;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
if (e.preventDefault) e.preventDefault();
return false;
}
It doesn't stop the swiping behavior, but does prevent clicks on all links on the page...
Any help is much appreciated. Thanks!
I had the same problem, but on the iPad, and couldn't find anyone who had been able to solve the problem in the general case, but I believe I have come up with a solution that works.
The solution is (in Javascript) --
document.addEventListener('touchmove', function(e) {
if (e.preventDefault) { e.preventDefault(); }});
Simple, no? It works by preventing the default behavior on 'touchmove' events, so the swiping of the background doesn't happen. It doesn't affect the simulated click events.