I know how to hide CSS from all browsers except the iPhone: see How do I apply a stylesheet just to the iPhone (and not IE), without browser sniffing?
But: how do I hide CSS from the iPhone, but not other browsers?
You could possibly use #media queries:
<link rel="stylesheet" href="noniPhoneStylesheet1.css" media="only screen and (min-device-width:490px)" />
Which would automatically exclude iPhone browsers from downloading that particular stylesheet (the iPhone's screen width being 480px); so putting any styles you want to hide from the iPhone into that stylesheet should work. Although, obviously, it'll also block that stylesheet from other devices that respect media-queries and have a screen width below 490px.
You can still do the conditional check, for iPhones append the iPhone CSS otherwise your normal CSS.
var agent=navigator.userAgent.toLowerCase();
var isIPhone = ((agent.indexOf('iphone')!=-1);
if (isIPhone)
document.createElement("style")... //iPhone CSS
else
document.createElement("style")... //normal CSS
Or a simple redirect to a page without the CSS, or use PHP to detect iPhones and deliver them a page without the style — something with a flow of:
if iPhone {
echo //page without CSS
else {
echo //page with CSS
}
I actually ended up going with a slightly different, and very ridiculous, solution that uses media queries and getComputedStyle to redirect to a mobile site if we’re on an iPhone-like device.
<style media="only screen and (max-device-width: 480px)">html{border-top-style:dashed;}</style>
<script>
if(window.location.search.indexOf("?m=t")==-1 && window.getComputedStyle) {
var mobile = false;
if(window.getComputedStyle(document.getElementsByTagName("html")[0],null).getPropertyValue("border-top-style")=="dashed") {
var mobile = true;
}
if(mobile) {
window.location.replace(window.location+"?m=t");
}
}
</script>
I’m sure I got the getComputedStyle idea on Stack Overflow, but I can’t remember where.
Related
EDIT: This was a total rookie error on my part. I was editing a different fileset to the one I was testing. Sincere apologies to all who answered to help me out. I've upvoted all answers as I at least learned a little more on media queries from you all, but none provided the answer. Advice pls on what now to do with this ticket?
This is a busy topic on the site, but I haven't seen the solution for this problem.
The viewport tag is present. I'm using:
<meta name="viewport" content="width=device-width,initial-scale=1.0">
When I resize the browser window in Chrome, it works fine, and I can see it snapping to new breakpoints as they are reached, however iPhone Safari displays the top left of the site only, with no sign of picking up any queries.
The CSS Media query I'm using for iPhone portrait is:
#media (max-width: 321px) { }
I'm using Bootstrap and LESS, so my media queries are at the end of the styles.
Sorry I'm not in a position to share code on this. It's an odd one — I'm hoping someone can see if there's something I may be missing.
EDIT
Here's a very basic example which is working on my iPhone. I can rotate from portrait to landscape and the bg color will change - so there's nothing wrong with the media query I'm using:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<style type="text/css">
body
{
background: blue;
}
#media (max-width: 321px)
{
body
{
background: red;
}
}
</style>
</head>
<body>
Here is my content...
</body>
Edit
What solved this for me is a double ("or"-operated) media query, for either max-device-width or max-width. It's like David Rönnqvist's first suggestion, but it was only putting max-width, max-device-width BOTH in the media query that worked for me.
#media screen and (max-device-width:640px), screen and (max-width:640px) {
/* styles here */
}
BBTony, I hope this works for you.
I'm keeping the below because it is a fuller description of the problem than i've found anywhere else. I disliked my first solution (below the line) so much that I re-researched for the thousandth time - thanks to this post which gave me the above solution without the ridiculous !importants.
Edit: this also worked, but it's extremely inelegant: Putting "!important" on every line of the media query conditional CSS.
I was reluctant to propose that as an answer, but after going bonkers researching this for 3 days, it was the first thing that worked for me.
Full description of the problem: I had similar symptoms as BBTony. I had the viewport tag (and I had it above the stylesheets as recommended).
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
My media query, intended to catch any smallish device, was being ignored by an iPhone 3gs running iOS 5.1, but the same media query was being properly picked up by an iPhone 4s running iOS 6.
#media only screen and (max-device-width:640px) {
/* many styles here */
}
Very oddly, while most declarations within the media query were being ignored by the older iPhone, some of them were being respected. The newer iPhone 4s however respected all the CSS within the media query, as expected. On Safari desktop, the media queries all worked perfectly, snapping at both the breakpoints (there are 2).
I linted my CSS through several different linters, after reading here that CSS errors can cause mobile browsers to ignore media queries. After making certain that my CSS was compliant, and just for the hell of it, I put !important declarations after each and every line of CSS within the media query - like 80-100 !importants.
Presto.
I can't tell you how mad it made me that this even worked, and I'm curious why the old iphone would only respect the conditional with !important in this case.
I've previously used this for my site and it worked as iPhone specific media queries for me
#media only screen
and (max-device-width: 480px)
and (orientation:landscape) {
/* iPhone landscape */
}
#media only screen
and (max-device-width: 480px)
and (orientation:portrait) {
/* iPhone portrait */
}
Answers to other questions like this seem to suggest that 480px for the max-device-width is what you should go for in your media query.
I'm trying to teach myself how to make a mobile version of a website, so I started off with something basic.
I have the following code
<body>
You are using...
<p class="mobile">
Mobile
</p>
<p class="desktop">
Desktop
</p>
</body>
with the CSS
#media screen and (max-width: 480px)
{
p.desktop {
display:none;
}
}
p.mobile {
display:none;
}
Basically, I want either "mobile" or "desktop" to display depending on which device you're using. When I navigate to the site on my desktop it says "desktop", so that seems fine.
But when I do so on my iPhone it still says desktop.
I have tried increasing the max-width to 640px which is the iPhone 4S' resolution. But I still have no luck. What am I doing wrong?
The default viewport on an iOS device is somewhere around 1000 pixels. You may notice when you pull up your test page that it doesn't look like it's a 320px wide - it's way zoomed out.
You need a viewport meta tag in your page head that sets the viewport width to that of the device:
<meta name="viewport" content="width=device-width">
Once in place, you'll find your #media query works nicely (although you need a p.mobile { display: block; } bit to make the "mobile" text show up).
I've been asked to retrofit an existing website with a mobile layout. The website was built on a Wordpress Twenty11 framework, so I decided to build the mobile layout using the existing media queries in that framework.
Now, my mobile layout looks great on any desktop browser dragged down to be less than 420px wide, but on iPhone & Android mobile browsers it just loads the full-width webpage anyhow. Full web experience, woot!
Client unhappy. Wants mobile design to show up on all iPhone browsers. So now I need to work out why the mobile browsers insist on showing the page at the full desktop width, ignoring the mobile CSS entirely.
Here's my media queries, down the bottom of the main style.css document:
#media (max-width: 800px) {
/* Design starts to get a little more fluid */
}
#media (max-width: 650px) {
/* Design gets quite a lot more fluid, and columns start dropping off the edge to below main content */
}
#media (max-width: 450px) {
/* Totally changed navigation for small viewports, main content takes up whole viewport */
}
All of these do what I want when I manually resize a browser window on a desktop machine. They also do what I want when I test them in next-to-useless iFrame-based "iPhone emulators". But all mobile devices so far tested stubbornly show the full-width layout, zoomed really far out and unreadable.
Is there something I should be adding to those media queries to MAKE the mobile browsers display the mobile CSS? Or should I be going with a different strategy altogether, such as user-agent detection or similar?
EDITED TO ADD:
Something like this line in header.php, I am guessing:
<meta name="viewport" content="width=960,
maximum-scale=1.0">
should in fact be
<meta name="viewport" content="width=device-width,
maximum-scale=1.0">
right?
You should add min-width parameters to your media queries because at the moment someone with a small screen will be getting rules from all three of your media queries since it's max width will be less than 800px.
#media (min-width: 651px AND max-width: 800px) {
...
}
#media (min-width: 451px AND max-width: 650px) {
...
}
#media (max-width: 450px) {
...
}
If you attempt to get too complex with media queries you'll run into tons of problems. Different browsers handle them differently making them less than ideal for a production environment.
A method that I like to use is to create a simple JS event handler for the window.resize event that only adds a class to the <html> element to specify what screen-break-point the user is at. Then in your CSS you just prefix rules with the breakpoint-classes:
$(window).on('resize', function () {
var w = $(this).width();
if (w > 1400) {
$('html').addClass('widescreen-viewport');
} else if (w > 1024) {
$('html').addClass('desktop-viewport');
} else if (w > 767) {
$('html').addClass('tablet-viewport');
} else {
$('html').addClass('mobile-viewport');
}
});
Sorry for the jQuery but this is a way I know works for sure.
Then your CSS would be something like:
#some-element {
/*default styles*/
}
.widescreen-viewport #some-element {
/*widescreen styles*/
}
.desktop-viewport #some-element {
/*desktop styles*/
}
.tablet-viewport #some-element {
/*tablet styles*/
}
.mobile-viewport #some-element {
/*mobile styles*/
}
This method will receive better browser support as it requires JS to be enabled but other than that, it'll work back to IE6/5.5 and other browsers from that time.
Im making a web page that has a 'fullscreen mode'. Its a normal web page until you click a button and then a div is created that has 100% height and width, and the old content is hidden. The fullscreen mode provides another button to return to non fullscreen mode, which hides the div and unhides the original content.
This works fine except that I also want to hide the browser chrome with this JavaScript method:
setTimeout(function() {
window.scrollTo(0, 1) },
100);
The JavaScript scrolls down the page enough so the browser chrome is no longer visible. The problem is this requires the page to be taller than the viewport so its able to scroll. If the content has a height of 100%, this cannot happen.
My current workaround is to to add a padding of 70px to the bottom of the fullscreen div. This works fine for the iphone, but then this unnecessary spacing is added to all devices. This may break the fullscreen effect I want in some, and creates unnecessary scroll bars in dektop browsers.
Is there a smart work around? Or do I need to detect the browser chrome height or get it from detecting the device, and add this padding accordingly?
Thanks
The best way is to write dedicated css for devices and their orientation.
You can see the media queries to detect the orientation of the devices ans set the css according to that.
<link rel="stylesheet" type="text/css" href="ipad.css" media="only screen and (min-device-width: 481px) and (max-device-width: 1024px)" />
<link rel="stylesheet" type="text/css" href="iphone.css" media="only screen and (max-device-width: 480px)" />
To hide bar use this script:
if (navigator.userAgent.indexOf('iPhone') != -1) {
addEventListener("load", function() {
setTimeout(hideURLbar, 0);
}, false);
}
function hideURLbar() {
window.scrollTo(0, 1);
}
I read a lot of articles about how build a web site for iphone, all people have more and less the same technique for optimization a website for iphone.
I follow the suggestions, I use the difference css file (iphone.css - i just need the optimization for iphone not all phone) and I tried with a IE conditional and without. I tried also a inline css, inside a common style.css. And finally i also add a meta tag with scalation...but nothing! The iPhone doesn't want read my rules.
I don't have a iPhone i use iPhoney program (I also tried something else but they aren't very good) and sometimes I check form friends iPhone.
My problem is that my main menu that is long like all the page break and going down over the content. Just this. I just need to tell that the screen is more little (min-width-divide) but it doesn't work! And the css doesn't work (i tried to put #menu: display:none and the menu was still there). But the directory is right because if i see the site form my laptop i can see the css and can go inside!
The web site is built in wp, i don't know if it's important but it's so simple web site.
Make sure you target the iPhone with something like this:
<!--[if !IE]>-->
<link type="text/css" rel="stylesheet" media="only screen and (max-device-width: 480px)"
href="mobile.css">
<!--<![endif]-->