Retina Display Media Query
For including high-res graphics, but only for screens that can make use of them. "Retina" being "2x":
@media
(-webkit-min-device-pixel-ratio: 2),
(min-resolution: 192dpi) {
/* Retina-specific stuff here */
}
Or other highish-res:
/* 1.25 dpr */
@media
(-webkit-min-device-pixel-ratio: 1.25),
(min-resolution: 120dpi){
/* Retina-specific stuff here */
}
/* 1.3 dpr */
@media
(-webkit-min-device-pixel-ratio: 1.3),
(min-resolution: 124.8dpi){
/* Retina-specific stuff here */
}
/* 1.5 dpr */
@media
(-webkit-min-device-pixel-ratio: 1.5),
(min-resolution: 144dpi){
/* Retina-specific stuff here */
}
Old Stuff (don't use, keeping for posterity)
@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) {
/* Retina-specific stuff here */
}
This is more future proof...
@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) {
/* Retina-specific stuff here */
}
Notes:
- The super weird
min--moz-device-pixel-ratiois probably a bug, might wanna put in-moz-min-device-pixel-ratioalso in case they fix it but leave it prefixed. - Here's the spec on resolution units.
Example:
Let's say you had three major breakpoints in a design. This design also had a large background graphic and you wanted it looking it's best on any screen (retina or not) and not waste any bandwidth. You'd set up 6 media queries, one for each breakpoint and one for each one of those breakpoints on retina. Then you'd override the background image all the way down.
@media only screen and (min-width: 320px) {
/* Small screen, non-retina */
}
@media
only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 320px),
only screen and ( min--moz-device-pixel-ratio: 2) and (min-width: 320px),
only screen and ( -o-min-device-pixel-ratio: 2/1) and (min-width: 320px),
only screen and ( min-device-pixel-ratio: 2) and (min-width: 320px),
only screen and ( min-resolution: 192dpi) and (min-width: 320px),
only screen and ( min-resolution: 2dppx) and (min-width: 320px) {
/* Small screen, retina, stuff to override above media query */
}
@media only screen and (min-width: 700px) {
/* Medium screen, non-retina */
}
@media
only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 700px),
only screen and ( min--moz-device-pixel-ratio: 2) and (min-width: 700px),
only screen and ( -o-min-device-pixel-ratio: 2/1) and (min-width: 700px),
only screen and ( min-device-pixel-ratio: 2) and (min-width: 700px),
only screen and ( min-resolution: 192dpi) and (min-width: 700px),
only screen and ( min-resolution: 2dppx) and (min-width: 700px) {
/* Medium screen, retina, stuff to override above media query */
}
@media only screen and (min-width: 1300px) {
/* Large screen, non-retina */
}
@media
only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 1300px),
only screen and ( min--moz-device-pixel-ratio: 2) and (min-width: 1300px),
only screen and ( -o-min-device-pixel-ratio: 2/1) and (min-width: 1300px),
only screen and ( min-device-pixel-ratio: 2) and (min-width: 1300px),
only screen and ( min-resolution: 192dpi) and (min-width: 1300px),
only screen and ( min-resolution: 2dppx) and (min-width: 1300px) {
/* Large screen, retina, stuff to override above media query */
}
Is the Mozilla team aware of the typo in the declaration ?
the dev team is aware of it and as of firefox 16 they recommend exactly what is in the future proof version above.
Will we need to use media queries for non retina displays so the retina displays don’t download background images twice?
Yes, that would be a good idea.
But then devices without pixel-ratio (or any media query) support won’t see your “normal” resolution styles?
These are great snippets, and making good use of them.
But thinking about this a bit more, iIsn’t this a bit of a Wild Goose Chase? Where does this end? There are consumer LCDs entering the marktet capable of 4k and 8K resolution. Is there a better solution to support this wide range of DPIs quickly approaching?
Is SVG the only viable future-friendly solution?
I second your argument Rob this is just maddening, em should be the standard for font management and svg the same for images, the web is just a collection of assembled hacks and there seems to be no going back. It was fun at times but its becoming annoying to say the least.
I believe the web has always been an assembly of hacks! Remember when tables were used build layouts? Images to display good typography?
In many ways, we’re now less hack-ey than ever!
(And yeah, SVG and icon fonts have an exciting future for graphics but not photos.)
Would you want to serve the same images to 1.5x screen ratios? There’s some android devices out here with weird ratios, I’d usually spec 2x images to everything from a 1.5 ratio up and contain them with background-size.
As someone pointed out this method also requires some thought as to how you’re going to support older browsers without media queries…. Mobile first default, IE stylesheets, or feature detected classes perhaps? (I favor the latter)
I thought long and hard about that until I found some JS out on the web that will basically add media query support to our grandpa holding up the fast lane… IE.
I start out by developing general base styles and make sure everything is decent between 1024-1280px wide, as this low-res is likely to be found on those who still use old IE. I set the body to max-width of 1280 so it stops scaling if old IE is running on a larger screen. Then, I set max-width back to 100% in a media query to let it use all the real-estate available. I add the JavaScript I mentioned above, then close IE immediately and discontinue any tweaking for it and begin building for real browsers. In the day that web clients want basically four interfaces in one, it’s just not feasible to assume you can build code for phones, tablets, SD, HD, “retina” iPads (seriously… people who buy iPads have no use for 3000px displays – this is ridiculous – they use them for Facebook) AND on top of all of it, support Internet Explorer 7? I get it, it’s all supposed to be backwards-compatible but it’s not.
If a client asks for IE8 support on top of all of the above, we have to charge more because of the significant amount of time it adds to the project. If they also throw IE7 in there, we take 1.5x the additional IE8 support cost, and that’s their legacy browser support cost. Usually, when we do user analysis and look at trends, they realize that a.) legacy IE is “dead enough”, b.) the cost to tweak and hack everything to display as designed/well on old IE is nowhere near worth the time, investment or code clutter because, c.) someone on IE7 clearly doesn’t care/notice the web looks/works like crap to them (or else they would have upgraded by now) and/or don’t know how to use a computer well enough to find web information and aren’t going to effectively receive the purpose of the site, if not are lost or aimlessly browsing. The only other people who are on old IE are possibly corporate workers at companies with poor IT leadership who lock users down to old IE7 to “ensure security” (WHAT?!) or have an old web app coded by careless fools that only works in IE7 (and haven’t found out how to work compatibility mode in IE9.) Keeping in mind that this corporate user is very, very rare, doing anything beyond the bases to support IE is beating a dead horse. Businesses so cheap they can’t ditch a web app they bought in 2001 (that’s probably never worked and held back workflow the entire 10 years they’ve had it) are probably not after a modern HTML5 responsive web app or anything that would require marketing with such a website. And if they are, they’ll get the information they need – just not how your designer wanted it. You just can’t blast out the timeline to support every ancient technology in the world. If you build it right to start with, it will support old IE “well-enough” to provide information – which is what the web is for. If we’re going to support IE7, what’s stopping a client from asking for AOL support. Most are simply unaware of the required work until they see the longer timeline & legacy costs. Makes no sense when all that work is done and they still have a crappy experience because they haven’t upgraded. If anything, put a message in the footer saying it won’t display properly because they haven’t bothered to upgrade yet.
IE sucking behind, you know what also sucks? This BS:
-webkit-min-device-pixel-ratio: 2
min–moz-device-pixel-ratio: 2
-o-min-device-pixel-ratio: 2/1
min-device-pixel-ratio: 2
and now that Windows 8 is out and IE10 is available, we get another:
-ms-min-device-pixel-ratio: 2
And I want to slap Mozilla for making some random declarations different than the rest. Also love how Opera uses the webkit conditionals because “web developers are being lazy and not including all of them.” First off, it is ridiculous to blame web devs for omitting code when the code is there… five effing times, and you’re just choosing not to read the base declaration because it’s not “standardized” yet, and W3C’s CSS people need to get a clue and start doing rolling standards with CSS as they had to with HTML, and second of all, no one uses freaking Opera. I omit Opera on purpose, bitches. Don’t act like I’m lazy when really your usage share on my analytics sheets are 0.2%. The lone Opera user that probably didn’t even speak the same language and accidentally wound up on that page had to see the fallback experience. Ohh no! Big deal. Don’t care.
Most of the time when I only include webkit conditionals it’s because the declaration is targeting mobile devices. With that statement, you can hit the Droids, iOS and Blackberrys with one punch. So good job Opera, you’re applying styling that’s meant for an iPhone. Fail. Yes, I know Mozilla makes a Firefox for Android that barely functions, Opera has like 15 browsers in the Android market that no one uses and has made browsers for various ancient handheld technology that’s not CSS3 capable, nor used anymore, nor displayed large enough on the hardwares two-pixel screen to show anything but your web’s logo. I’ll only hack my code to pieces if the usage numbers are there to back it, and IE on mobile hasn’t even acquired enough users for me to care to add 500 lines of “-ms-stupid-conditional-code-killer” with the other mobile declarations. Don’t talk to me about lazy web developers when CSS has taken on 5 times as much code to be authored because of this and causes nonstop issues such as Mozilla’s inability to stay with the format of the rest. No, we aren’t enjoying having to Google what every browser’s little hack is called for every little attribute. No, I’m not including all of that code for browsers that are used so little that I don’t even bother testing in them. Go ahead and read the -webkit- declaration Opera, just remember it doesn’t matter because when it comes to my users, no one will see it. I don’t want to hear the “oh Opera just said a lot of developers don’t know they’re forge…” because that’s BS too. No one forgets it. Many remove it from code snippets they paste in from tutorials. This is why we build fallbacks. Didn’t forget. Not lazy. Don’t care.
I cannot believe we are still having to do this, and I’m sure in the future we’ll be fighting about when it’s appropriate NOT to keep doing this, but one thing’s for sure – I want to punch some people in the face for not addressing developers issues on the basis of standardizing the same way we did in the 2000s… back when the web was broken and hacked to pieces with sht code. The browsers are ready because we’ve been using it already. Our clients are ready, they’ve been demanding it for years already. Users are ready, they’ve got it on 4-inch screens already. Many, many new CSS specs are ready & waiting for standardization. To me, these are already standardized because they display the same across all browsers and are used in mass across the web. If I hear “backwards compatible” as I hack out 500 lines of code into 2500 to support the technology that’s actually being used today, I’ll kill someone. Get a clue. Electronics manufacturers don’t make the technology to last longer than 5 years (two if we’re talking about phones or Macbooks) and marketing directors to information archivists alike don’t give a flying crap that some ’90s technology that’s in a landfill by now doesn’t recognize their CSS. If it doesn’t recognize it, it will ignore that declaration, life moves on and in the end, no one even knew the difference, and if they did – they didn’t give a sht, if they did give a sh*t, they wouldn’t be trying to browse the web on a god damned Wii. Information is in the markup, if that’s there, then the web has done its job. I understand their logic, but I just think they have broken the web once again by forcing major version standardization, not understanding the real-world and how the web they’re working on is actually managed and are moving several-dozen times slower than the technology itself. Their little experimental hack schema has become a permanent part of the next decade of CSS and has already started to break things.
Lazy developers… screw Opera.
^ What he said.
Hey Chris, I just wrote up some thoughts on how you simplify your future-friendly example. I always thought all the vendor prefixed media queries were a headache. When I looked at this some more, I realized you only need 2 checks in your retina/high resolution media query. Hopefully this helps other devs as well.
Get this as a Resolution mixin for SASS: http://blog.14islands.com/post/37259603246/sass-resolution-mixin
// only include 1x size image for 'non-retina' screens @include if-max-resolution(1.49) { background-image: url('img/footer-anchor@1x.png'); } // only include 2x size image for 'retina' screens @include if-min-resolution(1.5) { background-image: url('img/footer-anchor@2x.png'); }Thanks David for the mixin;
Looks like IE9 had a problem with this definition mentioned above.
In my test IE9 loads the declaration inside the media query if this line is inside:
Can anyone else reproduce this?
I am facing the same problem. Did you manage to solve this issue?
Did you manage to solve this, we are experiencing the same problem on some PCs (not all, strange?) that is running IE9.
Until every browser decides to get together and come up with a single solution we will always be venting our anger in terms of device compatability. Apple you may have the gorgeous way of displaying your info on your marvelous devices but spare a thought for designers having to work with this tech. Now we are producing 2 images when one should be enough……..
OK, Andrew.
But why not tell us how you really feel?
;)
@Andrew: well you couldn’t have been more straight to the point… ;) Just serve ‘em a plain text file.
These solutions are great for images you can identify in your styles but what are the best solutions for images placed within content areas such as blog posts via WordPress?
I am having issues with images that may be syndicated through RSS on partner sites.
@Jess You could look into Hammy: http://wordpress.org/extend/plugins/hammy/
So all this retina and I don’t have one. Can I care less… Ah whatever. So how would us developers know its working if we can’t see it? Is there a trick to this?
Any help on seeing the image change on a non retina display to know its working and aligned correctly would be nice. No problem coding for it just need to be able to see the changes are ok and fixed.
There’s an article in the W3C’s Blog that says:
And thanks to the new implementation of the
dppx(dots per px) and some problems with the ratios lowers than 2 we can write:@Andrew – I totally agree – brilliant rant! lol
I think this is only going to get more and more complicated. This should be headache for device manufacturers or browser engines.
Because:
1. Not all developers can afford the devices and test.
2. Everything is going to get more complicated when there are huge manufacturers.
We can make rules for the manufacturers or browsers, but not developers.