Media Query won't swap in High-Res for retina display

Greetings. I have been experimenting with using Media Queries to swap out images should somebody view this site using a phone with Retina Display capabilities. As many times and different ways as I’ve tried this, it’s never worked. I have cross referenced my CSS with w3.org (http://www.w3.org/TR/css3-mediaqueries/) and appear to be doing everything correctly.

To test this at the link below, I just have a simple div which uses CSS (background-image) to select it’s background image. Now when somebody uses, say an iphone 4s, It would swap in an image twice the size and re-size it at 50% of its original size so that it appears nice and sharp for viewers with a retina display device.

What I did for testing to make it obvious the swap has occurred, is, I wrote the word “Retina” in large letters over the high-res version of the image. This way it will be very obvious to tell if things are working.

My CSS is a follows:

/* Main CSS */
#mainDiv { width:320px; height:200px; background-image:url(img/image1.jpg); background-repeat:no-repeat; }

/* Retina Optimization */
@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) {

#mainDiv { background-image:url(img/image1@2x.jpg); background-size:320px 200px; }

}

Dev URL is: http://www.savagepixels.com/retina/index-retina.html

The higher res version of the image is image1@2x.jpg.

Does anybody see what I am missing? Seems like it should be a pretty simple deal. And who knows? Maybe it’s actually working everywhere but on my iPhone. I’d never know, would I?

Thanks a million.
| scott

Hi,

I don’t have a retina device to test the code out but I can tell you that the rule that will be applied will be the last one in the cascade.


<link type="text/css" rel="stylesheet" href="css/retinaTest_mediaQueries.css" />

<style type="text/css">

body {
	background-color: #ffffff;
	font-family: Georgia, "Times New Roman", Times, serif;
	font-size: 12px;
	line-height: 16px;
	color: #666666;
	margin: 0;
	padding: 0;
}

[B]#mainDiv { width:320px; height:200px; background-image:url(img/image1.jpg); background-repeat:no-repeat; [/B]}
</style>

You are setting a media query and then immediately you trump it with a rule that follows it!

This rule wins out as it is last in the cascade no matter what previous media queries you set (at the same weight).


#mainDiv { width:320px; height:200px; background-image:url(img/image1.jpg); background-repeat:no-repeat;

Although you target elements via media queries that doesn’t mean that you exclude the same element anywhere else in the stylesheet. Folow the same process that you would to over-ride any previous style and place the media queries after the original styles that you are modifying.


<style type="text/css">

body {
	background-color: #ffffff;
	font-family: Georgia, "Times New Roman", Times, serif;
	font-size: 12px;
	line-height: 16px;
	color: #666666;
	margin: 0;
	padding: 0;
}

#mainDiv { width:320px; height:200px; background-image:url(img/image1.jpg); background-repeat:no-repeat; }

</style>
<link type="text/css" rel="stylesheet" href="css/retinaTest_mediaQueries.css" />


Unless the image is decoration only, it’s better to place it in the HTML. And you don’t need two images. You can just use the retina-quality image for all devices. Whether you place the image inline or set it as a background image, you might as well use the larger one. It doesn’t have to have a larger file size. It’s been found that if you increase the dimensions of an image but save it at a lower quality (thus keeping down the file size) it works beautifully on retina devices, and you can actually get away with smaller file sizes than you’d normally use.

Thanks Paul. That makes sense. The media query needs to come after the CSS that it modifies. I switched it and it looks to be working … only now the page appears completely blank. This tells me the media query is taking effect, but maybe I got something wrong in my overriding rule or something and now the div just displays nothing as it’s background. Not sure why. You’d obviously need an iphone to see, but on my iphone 4s the screen is just blank. Any ideas what’s wrong with the following?

'/* Retina Optimization */
@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) {

#mainDiv { background-image:url(img/image1@2x.jpg); background-size:320px 200px; }

}

So, Ralph? To do that you would just use your CSS to shrink the image on the non-retina version?

HI,

This works for me:


<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Retina Display Testing</title>
<meta name="viewport" content="initial-scale=1.0, width=device-width, maximum-scale=1.0"/>
<style type="text/css">
body {
	background-color: #ffffff;
	font-family: Georgia, "Times New Roman", Times, serif;
	font-size: 12px;
	line-height: 16px;
	color: #666666;
	margin: 0;
	padding: 0;
}
#mainDiv {
	width:320px;
	height:200px;
	background-image:url(http://www.savagepixels.com/retina/img/image1.jpg);
	background-repeat:no-repeat;
}

/* Retina Optimization */
@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) { 
  
#mainDiv { background-image:url(http://www.savagepixels.com/retina/img/image1@2x.jpg); background-size:320px 200px; }

}
</style>
</head>

<body>
<div id="mainDiv"></div>
</body>
</html>

It looks as though you have the wrong path to the hi res image as it is not in the CSS directory where you are looking for it. You need to come up one level and then into the image folder.

I think its neater to keep the rules together in the same file anyway rather than splitting them up all over the place.

You can use CSS and/or HTML if the image is in the HTML. But you do the same for all devices, as you need to force the image into smaller dimensions on all devices.

Thanks Paul … being somewhat of a newb, I didn’t realize the image path was based off where the actual css file is stored as opposed to the where the document itself is. My image targeting was based off the root directory and that’s where I went wrong. Actually, I had two problems going on at once, which is usually trouble. The secondary CSS was placed ahead of the primary css in the DOM and incorrect file targeting. Thanks again.

Cool Ralph … is there a link y9ou can paste in so I can read more? Very interested since I will be doing this a lot.

This is a good post that details what I was talking about: http://blog.netvlies.nl/design-interactie/retina-revolution/

Thanks for all the help.