Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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/[email protected]);}
}

/* @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/[email protected]);}
}

/* @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/[email protected]);}
}

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?

like image 988
Mastrianni Avatar asked Feb 06 '15 20:02

Mastrianni


2 Answers

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/[email protected]);} } 

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):

  • CSS media resolution
  • picture element
  • srcset attribute
like image 192
Alexander O'Mara Avatar answered Sep 20 '22 11:09

Alexander O'Mara


Really use the img[srcset] attribute. Its support is much better than state in another answer. Current Chrome and Safari do support this attribute. And we know that, Firefox 38 and IE 12 will also support it. Additionally the syntax allows you to do simple progressive enhancement and you don't need to write complex media queries.

This is how it looks like:

<img src="img/[email protected]" srcset="img/[email protected] 2x, img/[email protected] 3x" /> 

And in case you want to add support to non-supporting browsers, you can choose between different polyfills.

In case you use a polyfill you might change the markup to this:

<img srcset="img/[email protected], img/[email protected] 2x, img/[email protected] 3x" /> 
like image 33
alexander farkas Avatar answered Sep 22 '22 11:09

alexander farkas