I am trying to implement alternate layouts for both the iPad/iPhone and older iPhones as well.
I have established that the best method is to use #media from the CSS3 spec.
As such these are my media queries at the minute:
#media screen and (max-width: 1000px) { ... }
Above is for small desktop and laptop screens.
#media screen and (max-width: 700px) { ... }
Above is for the iPad and VERY small desktop/laptop screens.
#media screen and (max-device-width: 480px) { ... }
Above is for iPhone 3GS- and mobile devices in general.
However, the new iPhone 4 with Steve Jobs's all-singing all-dancing "retina" display means that it has a pixel ratio of 2-1 meaning 1 pixel actually appears to the browser as 2x2 pixels making its resolution (960x640 - meaning it will trigger the iPad layout rather than the mobile device layout) so this requires ANOTHER media query (only so far supported by webkit):
#media screen and (-webkit-min-device-pixel-ratio: 2) { ... }
Now, the thing is... I want my nice shiny new iPhone 4 layout amalgamated with the iPhone 3GS and mobile device layout as they will both have exactly the same inner CSS code,
Therefore making my question;
How do I create an #media rule that points both the iPhone 4, 3GS and other mobiles to the same styles?
Because the iPhone and iPod touch measure max-device-width in logical pixels rather than physical pixels even with the Retina display (as they should), the original media query used for the iPhone should be enough:
#media only screen and (max-device-width: 480px) {
/* iPhone CSS rules here */
}
You'll only need (-webkit-min-device-pixel-ratio: 2) if you need to target the Retina display separately.
BoltClock's answer seems pretty good to me at the moment.
However, thinking in to the future, if Apple (or another manufacturer) releases another device with a device pixel ratio of 2, this media query would be used for this device too.
I don't think it's out of the question to assume that this will happen, and that the new device could have a much larger screen, such as an iPad with a retina display.
To make this query only applicable to the iPhone 4 and previous iPhones (and any other device of a similar size)
#media screen and (max-device-width: 480px), screen and (max-device-width: [[IPHONE_4_WIDTH]]px) and (-webkit-min-device-pixel-ratio: 2) {
/* iPhone CSS rules here */
}
Unsure of [[IPHONE_4_WIDTH]] right now - don't have one on me, and some sites say 480, some say 960. Try replacing with both. (And let me know what you find :) )
I have been hunting for a way to specifically target the iPhone 3 / 3GS per the second part of the request. The most acceptable solution I've found is to tailor the media queries to the fixed parameters of an iPhone 3.
#media only screen
and (device-width:320px)
and (device-height:480px)
and (-webkit-device-pixel-ratio: 1) { ... }
In order to work this query requires that you use Safari's viewport meta tag to fix the browser to 100% with the following:
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
There are a small number of Android phones that will also get picked up on that query. With the Android Market showing 18.4% of active phones in the potential screen size range of 320x480, only a subset of that will match the device-pixel-ratio on the stock webkit browser. Not perfect, but better than nothing at all.
Lists of phone resolutions
Slightly outdated but thorough: http://cartoonized.net/cellphone-screen-resolution-by-size.php
Only 3 listed as a potential match here: http://en.wikipedia.org/wiki/Comparison_of_Android_devices
Android Market weekly snapshot: http://developer.android.com/resources/dashboard/screens.html
All information was considered as of post date.
Also per mernen's comment #2 to his post here are the docs to target Android devices by pixel density: http://developer.android.com/guide/webapps/targeting.html#DensityCSS
I'm not sure I follow your question. Did you try your queries on the iPhone 4? device-width is measured in logical pixels, not physical ones, so the iPhone 4 still fits the max-device-width: 480px criteria.
Same goes for high-end Android smartphones, which have a pixel ratio of 1.5: the Nexus One has a physical screen of 480x800, logical screen of 320x533.
Related
I have a webpage which I have created a media query for a resolution of 480px in width.
The iphone 4 correctly picks up this version but for some reason it overhangs the page its not using the actual resolution of the iphone 4 which is 640px in width its using a width of 320px. (i read somewhere that it does this for backward compatibility with apps developed for iphone 3)
Is there a way using a viewport or a media query to correct this? Or does someone have an example of how to implement an iphone media query, ive tried this with no luck.
Is there a way to stretch the 480px media query to fit the iphone?
This is my current viewport:
<meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=5.0; minimum-scale=0.5;" />
Media query - this does nothing and ive tried with just -webkit-device-pixel-ratio: 2 only
#media screen and (max-width: 480px) and (-webkit-device-pixel-ratio: 2) {}
This media query in css3 should detect any iphone or ipod
#media only screen and (max-device-width: 480px), only screen and (min-device-width: 640px) and (max-device-width: 1136px) and (-webkit-min-device-pixel-ratio: 2)
The way I understand it is that retina screens will still act as if they are the normal old screens. you act as if things are still 320px is the width. if you want something to take up the full width of an iphone in portrait then you would use 320px not 640px. Really you should be using percentages and ems though not exact px sizes.
Not sure if this answered anything, but I think you were wanting to know why if you set something to 640px it would hang off the edge and not just take up the width of the retina screen.
This must have been answered before, but I can't find a related question.
I've designed a responsive site, with css media queries going all the way down to correctly display on 320 wide.
Want I want is the iPhone4 (640 x 960) when in portrait mode (640 wide) to adhere to media queries as if it's display-width = 320 pixels instead. Rationale: even though the iphone has more pixels, I do want to display a simplified layout to those user, similar to users of non high-density phones.
Any way to do this, by specifying some meta-tag for these high-pixel density phones for example?
Of course, I could define separate media-queries for iphone 4 and the like with min-device-pixel-ratio: 2 but this leads to separate css media queries (one for low and one for high pixel density) which essentially have the same logic, which doesn't seem very DRY to me( http://en.wikipedia.org/wiki/Don%27t_repeat_yourself )
Strange thing is: the new Ipad 3 , with pixel density 2, DOES correctly render the way I want, i.e: it mimics (at least as css media queries are concerned) a device with half the resolution.
The iPhone 4 (and 4S) will respond to this meta tag:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
It's the "initial-scale" part that you're after. It will make the high res device act like it's 320px wide (or 480 in landscape).
There are other bugs around landscape orientation that you should be aware of.
Also, keep in mind that there is an orientation parameter available to media queries:
#media screen and (orientation:landscape) {
/* Landscape styles */
}
First: I think there's a typo in your question -- on a 640x960 display, 640 wide is portait mode, not landscape. Portrait is vertical, landscape is horizontal.
That said, if I'm reading your question right, you're asking how to target a retina display iphone using media queries for width.
The answer is that you can't -- both the retina display iphone and the non-retina display report themselves to the browser as 320x240. The difference, as you noted, is that the retina display has 2x pixel density, which you can target with media queries:
.avatar {
display: block;
width: 50px;
height: 50px;
background: url("50x50-avatar.png");
}
#media only screen and (-moz-min-device-pixel-ratio: 2),
only screen and (-o-min-device-pixel-ratio: 2/1),
only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and (min-device-pixel-ratio: 2) {
.avatar {
background: url("100x100-avatar.png");
background-size: 50px 50px;
}
}
This example is for displaying high-resolution images on retina displays, but you can use the same techniques for tweaking layout for retina displays.
So, in a nutshell, write your styles for the non-retina displays first, and then add retina display overrides using media queries, which should avoid your DRY concerns.
Further reading:
Retina iPad Specific CSS
Safari Developer Library: Configuring the Viewport
I haven't done any iPhone version yet, so I have this question,
In order to be able to browse the website properly -even if the user turns 90º his phone:
Shall i CSS set with's in px or in % ?
If you are programatically targeting the iOS devices such as the iPhone & iTouch then i would use pixels opposed to percentages, but if you are not targeting such devices and want a one stop mobile website for all (most smart-phones) then i would consider using percentages.
you can specificy min-width max-width and min-device-width and max-device-width in your media queries.
Here is a little more about media queries and the combinations that you can do;
/* Target iPhone Portrait */
#media screen and (max-width: 320px) and (orientation: portrait) { body{background:#F0F;} }
/* Target Android Portrait larger than 320px Width */
#media screen and (min-width: 321px) and (max-width: 480px) and (orientation: portrait) { body{background:#F00;} }
/* Target iPhone Landscape */
#media screen and (max-width: 480px) and (orientation: landscape) { body{background:#0F0;} }
/* Target Android Landscape */
#media screen and (min-width: 481px) and (max-width: 800px) and (orientation: landscape) { body{background:#FF0;} }
You can use % with one css class, and the size of components will be adjusted automatically.
You can also use px with two classes, one for portrait, one for landscape :
body[orient="portrait"] {
property: value;
}
body[orient="landscape"] {
property: value;
}
Personally I would use %, rather than px...
You will want the page to become 100% which ever way this is rotated, and then shift the content around accordingly.
The New York Times uses %, as you can see where the page is Landscape you are zoomed in further than Portrait.
If you are building a non specific website for iPhones (sub-domaine like iphone.mywebsite.com) I would suggest using CSS Media Queries as suggested by Xavier. It allows you to do much more than specify a min-width and max-width!
You can specify the type of device (but many devices aren't recognized like they should…) like: screen handheld print tv and many other
But most importantly you can also set if the browser window is in portait or landscape, it's resolution or aspect-ratio and so on…
As for % or px I'd definitely go for px, it's very difficult to have something working as you would wish using %. Because you don't necessarily want the same kind of information if your user comes with an iPhone or with an other device.
For exemple you could take out all the heavy images from your website for iPhone users because they'll probably be using a 3G connection and so making your site a lot faster to load!
A really nice example of what you can do with CSS Media Queries… unfortunately it0s not my work… :-(
I'm trying to test my web application in mobile Safari with a Retina display and only have access to iOS Simulator. My images are all rendering at 2x resolution. I realize that this probably makes sense on some level, but I actually want the images to render at their natural resolution.
How can I get img tags to render at their natural resolution in Mobile Safari on an iPhone retina device? (simulator or otherwise)
UPDATE
I am not writing a native application and calling out to Safari, I'm writing a plain ol' website and I want Safari to render my img tag images at full resolution both for retina and non-retina devices. (I'm aware, will accept and desire the fact that the image will be smaller on a retina device)
You need to make use of a media query. Retina won't automatically assume you are using 2x assets without it; that would cause all website graphics to render at 50% of their intended size. Disaster!
(from HTML5 boilerplate):
/* iPhone 4 and high pixel ratio devices ----------- */
#media
only screen and (-webkit-min-device-pixel-ratio : 1.5),
only screen and (min-device-pixel-ratio : 1.5) {
/* Styles */
}
You can also use ratio: 2 here to target only iPhone Retina, but some devices, like Samsung Galaxy S, also have a pretty high res - 220ppi, i think - though they aren't exactly double, so watch out for that. These devices respond to the 1.5 query. The ratio comes from the amount of actual pixels that take up a visible pixel. Pixel math, yay! Finally proves they are not (and have never been) absolute units.
Select the hardware in simulator
iOS simulator->Hardware->Device->iPhone(Retina) and run your app
If I understood you correctly here is similar question:
UIWebView and iPhone4 retina display
And an excellent blog post on this matter:
How to make your web content look
stunning on the iPhone 4’s new Retina
display
I want to change my web page CSS for web browsers running on cell phones, like the iPhone and Android. I've tried something like this in the CSS file:
#media handheld {
body {
color: red;
}
}
But it doesn't seem to have any effect, at least on the iPhone. How can I write my CSS to work differently on the iPhone etc, ideally without using javascript?
You can use #media queries:
<link rel="stylesheet" href="path/to/iphone.css" media="only screen and (max-device-width:480px)"/>
This particular version will target the iPhone (and any other device with a screen of max-device-width of 480px.
Apple, for the iPhone, though this is from memory so I can't be entirely sure of its accuracy, chose to disregard the use of handheld or mobile stylesheets, since it, and other iOS devices, were capable of rendering css more or less on a par with desktop browsers, via Safari. For other devices I'm unsure, exactly, how faithful they are, though the A List Apart article (linked-to above) gives a brief run-through of some.
Edited in response to comment, from #Colen:
Hmm, it looks like a lot of new mobile devices have higher resolutions (e.g. droid X is 854x480). Is there any way to detect those? I don't think those are being handled with this query.
I'm unable to say for certain, since I've no access to those devices, however another A List Apart Article: Responsive Web Design notes that:
Thankfully, the W3C created media queries as part of the CSS3 specification, improving upon the promise of media types. A media query allows us to target not only certain device classes, but to actually inspect the physical characteristics of the device rendering our work. For example, following the recent rise of mobile WebKit, media queries became a popular client-side technique for delivering a tailored style sheet to the iPhone, Android phones, and their ilk.
So I presume that they, Android devices, must be target-able by #media-queries, but, as noted, I'm unable to say with any certainty.
To target device-resolution, there is an example of:
<link rel="stylesheet" type="text/css" media="screen and (max-device-width: 480px) and (resolution: 163dpi)" href="shetland.css" />
Further reading: W3 Candidate Recommendation for media queries.
From this site there are a few other media queries that are useful in targeting iPhones/Android Phones:
// target mobile devices
#media only screen and (max-device-width: 480px) {
body { max-width: 100%; }
}
// recent Webkit-specific media query to target the iPhone 4's high-resolution Retina display
#media only screen and (-webkit-min-device-pixel-ratio: 2) {
// CSS goes here
}
// should technically achieve a similar result to the above query,
// targeting based on screen resolution (the iPhone 4 has 326 ppi/dpi)
#media only screen and (min-resolution: 300dpi) {
// CSS goes here
}
I was able to successfully use the max-device-width media query to successfully target Android phones, although I had to adjust the width up to 800px rather than the 480 listed. For iPhone 4, the -webkit-min-device-pixel-ratio worked to target the iPhone4 (max-device-width: 480px did not, I presume that will target the iPhone3 but didn't have one handy to test.)
I can see this getting quite messy, but if you have to support a multitude of devices and have custom CSS for each of them, as long as they support media queries it appears as it is possible to do what you have to to tweak each platform. And yes, I would code to standards first, so that as much CSS is resuable, but many times we are talking about presenting alternate layouts these days sized appropriately for the devices being used.
#media handheld refers only to those ancient tiny proto-html cellphones from years past which couldn't even really display web pages. The ePUB, MOBI, Tablet, community of vendors all said emphatically "H*ck no, we are not #media handheld devices!" because they were correctly worried that this would land them forever in a no-man's land subservient to "real" web pages.
With today's small devices with very high resolution displays we still don't have a good way to tell HTML how to display things "correctly" on large displays with relatively low resolution vs. small displays with very high resolution. And as a certified old fart my eyes would like to remind you that no, the answer is not just to make everything including fonts 2X smaller.
No, neither iPhone or Android browsers supports CSS #media handheld.
Look at using the media query 'hover'.
Put this in your SCSS file:
// At this point the CSS would target screens above 990px - but only
// if they support hover (i.e. laptops, PC's etc).
$point-at-which-use-large-screens: (min-width 990px) (hover hover);
.some-class-you-want-to-target {
// Some CSS to only apply to larger screens with mouse available.
#include breakpoint($point-at-which-use-large-screens) {
color: red;
}
}
After running grunt etc on the SCSS this will produce CSS looking like:
#media (min-width: 991px) and (hover: hover) {
color:red;
}