CSS media queries (Should know)
Making all devices download large Retina images, even if they cannot display them, is not ideal. Doing this makes users wait longer to view your content without any benefit. Using media queries in your CSS is one way to get around this issue.
Media queries check to see if the user's device meets specific conditions, and if not, supply an alternate style. These are particularly useful in adjusting your website to a specific media, screen size, device orientation, or display type.
It is recommended that you use a media query or other image replacement technique every time you're using Retina images rather than only supplying a large image. Media queries will help accomplish this for any images that are contained within your CSS, such as backgrounds, image sprites, and border images. This recipe will explain how media queries can be used for each of these images to target only Retina Displays.
Getting ready
To build our media queries we'll be using the images that we have previously created. These include a Retina and normal version of a background image, an image sprite, and a border image with a photo to wrap it around.
How to do it...
To get started, create a new HTML document called
mediaQueries.html
inside the/retina/
folder. Then inside of the basic HTML structure we'll add the non-Retina CSS code for a background image, an image sprite, and a border.First, we'll add a
box
style to hold our background image and the non-Retina version of the background image code.<style> .box { height: 200px; width: 700px; } .background { background: url(images/myBackground.jpg) repeat; }
Then we'll add the CSS code for our non-Retina image sprite.
.icon { background: url(images/mysprite.png); height: 40px; width: 40px; }
Next we'll add the code for a non-Retina border image.
.imageBorder { border-width: 10px; -webkit-border-image: url(images/myBorder.png) 10 repeat; border-image: url(images/myBorder.png) 10 repeat; }
Now we're ready to add a media query that will replace these images if the user is on a Retina Display.
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2) { .background { background: url(images/myBackground@2x.jpg) repeat; background-size: 250px 150px; } .icon { background: url(images/mysprite@2x.png); background-size: 80px 80px; } .imageBorder { -webkit-border-image: url(images/myBorder@2x.png) 20 repeat; border-image: url(images/myBorder@2x.png) 20 repeat; } } /* END OF MEDIA QUERY */ To complete the CSS, we'll add the styles to position our icons and the closing style tag. .icon1 {background-position: 0 0;} .icon2 {background-position: -40px 0;} .icon3 {background-position: 0 -40px;} .icon4 {background-position: -40px -40px;} </style>
To finish our code we'll just need to add some HTML to display our three types of images.
<div class="box background"></div> <ul> <li class="icon icon1"></li> <li class="iconRetina icon2"></li> <li class="icon icon3"></li> <li class="iconRetina icon4"></li> </ul> <img class="imageBorder" src="images/myImage.jpg" />
How it works...
To use a media query in our CSS, first we created all the code we would need for our non-Retina images. After that we created the media query statement. The order is important because CSS is cascading, meaning that code is read top to bottom. If the media query preceded the other code, its rules would be overwritten by the code following it.
Our media query is composed of four parts. First, @media
begins the media query statement. Then only screen
specifies that the device being used must be a screen (another media type could be print). Next, we specify that the min-device-pixel-ratio
must be equal to or greater than two. This targets the Retina Display (or any other similar display) because it has a pixel density that is two times greater than a standard display (some other devices use a ratio of 1.5). We also included the -webkit
vendor prefix to make sure that our code works on older Safari browsers. To keep our code short we only included one vendor prefix, but if you want full support you may need other prefixes (-o
, -ms
, -moz
). You can find out more about browser support at http://caniuse.com/. Finally, the brackets will enclose any style that we would like applied if these conditions are met.
When we write our styles within the media query we will be overwriting the code written previously, replacing a normal image with a Retina one. Any property that we don't specifically overwrite will remain from the above code. Each type of image has some specific considerations.
To create a background image, we overwrote our image file location with the @2x
version. Then we set background-size
to scale the large image down to the same size as the normal one. This allows the extra pixels to fill the Retina Display.
Creating an image sprite is similar to the background image. We first overwrite the image with the high-resolution version and then set the background-size
to shrink it back down. Note that we didn't need to set the height
and width
because the values used above are still correct. Each icon in the sprite needs to have its own positioning so the browser knows what part of the image to display. These background-position
values need to be stated after the end of the media query, otherwise they will be overwritten and you will only see the top-left part of the image.
To add a Retina border, first we overwrite the image with a @2x
version. Then we need to double the amount of pixels we are slicing. If you are using percentages you don't need to adjust the value. Also note that we're using the same border-width
property so it doesn't need to be included in the media query.
You'll find that media queries are a good solution when you have only a few specific images that you need to replace. On large sites with many images you'll want to use one of the other Retina solutions described in this book.
There's more...
Media queries can also be used to target specific screen sizes or device types. For example, to target a small screen you could use the code @media screen and (max-width: 480px)
. This can be used to have your site adapt well to a variety of screen sizes. This technique is called responsive web design, and it is a great alternative to creating different sites for mobile and desktop users. For more information on this topic, I recommend reading Ethan Marcotte's article on responsive web design at http://www.alistapart.com/articles/responsive-web-design/.