Mastrianni Mastrianni - 2 months ago 18
CSS Question

Media Queries for @2x, @3x, and @4x images

I am trying to support a variety of pixel ratios on the current site I'm developing. I also want to ensure I provide any required browser prefixes to support the widest variety of devices/browsers within reason. Also, I'm using SVG's wherever possible, but I need a solution for photographic images. Ideally, I'd like to provide:


  1. @1x image (Pixel Ratio 1.0)

  2. @2x image (Pixel Ratio of 1.25+)

  3. @3x image (Pixel Ratio of 2.25+)

  4. @4x image (Pixel Ratio of 3.25+)



My question is what would be the best way to go about writing the media queries to achieve this? My primary concern is that my arguments are correct for what I'm trying to achieve. I'd appreciate any suggestions or advice you have. Currently my code is as follows:

/* @1x Images (Pixel Ratio 1.0) */
#dgst_shopping_bag {background-image:url(img/shopping_bag.png);}

/* @2x Images (Pixel Ratio of 1.25+) */
@media only screen and (-o-min-device-pixel-ratio: 5/4),
only screen and (-webkit-min-device-pixel-ratio: 1.25),
only screen and (min-device-pixel-ratio: 1.25),
only screen and (min-resolution: 1.25dppx) {
#dgst_shopping_bag {background-image:url(img/shopping_bag@2x.png);}
}

/* @3x Images (Pixel Ratio of 2.25+) */
@media only screen and (-o-min-device-pixel-ratio: 9/4),
only screen and (-webkit-min-device-pixel-ratio: 2.25),
only screen and (min-device-pixel-ratio: 2.25),
only screen and (min-resolution: 2.25dppx) {
#dgst_shopping_bag {background-image:url(img/shopping_bag@3x.png);}
}

/* @4x Images (Pixel Ratio of 3.25+) */
@media only screen and (-o-min-device-pixel-ratio: 13/4),
only screen and (-webkit-min-device-pixel-ratio: 3.25),
only screen and (min-device-pixel-ratio: 3.25),
only screen and (min-resolution: 3.25dppx) {
#dgst_shopping_bag {background-image:url(img/shopping_bag@4x.png);}
}


Alternative 1: I've been considering utilizing the
<picture>
tag to accomplish this. I know you can provide alternative content for browsers that don't support
<picture>
, which would be my primary concern in utilizing it. Do you guys think that would be the best practice for providing photos for multiple pixel ratios?

Answer

Well, ignoring the obvious functional differences between a background image and an inline image element such as picture, there are a few pros and cons between the two.

Pros for inline image / cons for background-image:

There is no way to use a media-query for an inline style, so specifying a background-image requires declaring a selector for whatever elements require background images separate from the tag. This complicates this solution for dynamically created elements.

Also, if you are only interested in serving images with different pixel ratios, you can simply use the srcset attribute of an img tag instead of the picture element. The picture element requires more markup and has a number of features that are unnecessary for this, plus srcset is slightly better supported.

Pros for background-image / cons for inline image:

Resolution-based media queries are much better supported than the picture element and the srcset attribute. Some browsers do not support either the picture element or the srcset attribute at this time, although support is improving.

Incidentally, if you want to maximize browser support for Firefox versions older than 16, you can add the min--moz-device-pixel-ratio selector, which has the same syntax as -webkit-min-device-pixel-ratio. Here is an example using your CSS.

/* @2x Images (Pixel Ratio of 1.25+) */
@media only screen and (-o-min-device-pixel-ratio: 5/4),
       only screen and (-webkit-min-device-pixel-ratio: 1.25),
       only screen and (min--moz-device-pixel-ratio: 1.25),
       only screen and (min-device-pixel-ratio: 1.25),
       only screen and (min-resolution: 1.25dppx) {
    #dgst_shopping_bag {background-image:url(img/shopping_bag@2x.png);}
}

Best-practice?

Best practice would be to use media queries for places you need a background image, and either srcset or picture for places you need an inline image. However at this point, it may be more important to consider what browsers you need to support. For that, see the compatibly links (possibly considering that many people using older browsers are probably also using standard resolution monitors):