Make WordPress Core

Tagged: retina Toggle Comment Threads | Keyboard Shortcuts

  • Mark Jaquith 9:32 pm on August 1, 2012 Permalink
    Tags: HiDPI, retina   

    How to Develop for HiDPI (β€œRetina”) without a Retina MacBook Pro

  • Samuel Wood (Otto) 3:36 pm on July 4, 2012 Permalink
    Tags: , retina,   

    Fun with High-DPI displays 

    With the release of a lot of high-DPI displays (aka “retina” displays, but also others on both Android and iOS devices), it’s just a truism that images on these displays have tended to not look their best, all the time. High-DPI displays are having to scale up low-resolution images, and it’s just not great.

    There is a simple solution for this, using either CSS or Javascript tricks, but the basic principle behind it is to make an image twice as big on each dimension (four times the area), and then let the browser scale it down into the space it’s supposed to fit into. This lets the high-DPI displays have more information to work with and to make images which scale much better. The problem, of course, is that larger images require more space and bandwidth. With various CSS and JS techniques, you can target it such that the high-res images are only sent to browsers that really need them, saving on the bandwidth.

    Anyway, lately we’ve been making those sorts of changes to WordPress.org too. If you’re visiting on a high-DPI display, you may notice that the main header logo is of a higher quality, or you might have noticed that the Showcase looks particularly good, or that we now have some very high resolution images on the Logos and Graphics page. Little changes to the graphics, here and there. It’s an ongoing project to “retina-all-the-things”.

    Back in December, we made some changes to allow plugin authors to put banner images above their plugins in the directory, and the response has been great. So, now they get the high-DPI love too.

    Plugin authors already have the ability to make a banner-772x250.jpg or png file in their assets directory and have that be used for the banner image on their plugin listing. As of today, they can add a banner-1544x500.jpg or png file, for use on high-DPI displays only. When the website detects that the viewing browser both has a high-DPI display and the high-res image exists, then that image will be shown instead of the low-res image, but scaled to fit into the proper space. This makes them look particularly sharp on high-DPI displays.

    Now, before you go forth and create, please remember that one thing to keep in mind here is filesize. If you’re using photographic material for your banner, then it is highly recommended that you use the JPG file format. If you’re using drawn or generated materials, PNG is the favored format. However, in either case, you will want to apply high compression and try to keep those files as small as possible. Small files transfer to the browser faster. Also consider that a fair number of high-DPI displays will be phones, for example, and perhaps not using high-speed connections. So keeping that high-res file as small as you can would be a good thing. If you wish to use a PNG compression tool before uploading, that might be a good idea as well.

    And there you have it. Plugin authors, go forth, and show us your high-resolution banner skills! πŸ™‚

    BTW, if you want to see it, I gave my Pluginception plugin a high-res image, for testing. It’s a simple image with some well-defined lines that make the difference easy to spot if you’re looking for it. You’ll need a high-DPI display to see it though. πŸ™‚

    • John James Jacoby 3:50 pm on July 4, 2012 Permalink | Log in to Reply

      Added to bbPress.

    • Brian Layman 4:01 pm on July 4, 2012 Permalink | Log in to Reply

      What are the effective resolutions that are being seen in these high DPI devices? I would assume the current max width is over 1544..

      • Samuel "Otto" Wood 4:13 pm on July 4, 2012 Permalink | Log in to Reply

        It’s not about resolution as much as it’s about pixel density. The new Macbook Pro, for example, has 220 PPI, giving the screen a resolution of 2880Γ—1800. However, that resolution is clearly insane for a 15-inch screen, since you can’t see a pixel at that low of a size. So images have to be scaled up, and that’s where it falls apart.

        See, if I have a page on a normal screen that looks good at 1600px across, then try to display the same thing on a screen that’s 2880px across, it’s either going to be tiny, or I have to zoom in, making one “pixel” in the image take up more than one “pixel” on the screen.

        So, the trend is divorce the web “pixel” from the actual physical pixels on the monitor. If I make a 1000px wide image, but then use CSS to display it in a 500px wide space, then a browser on a very high-resolution monitor can recognize when the “500px” wide space is actually taking 1000 physical pixels on the screen, and thus properly display the high resolution image, while still fitting it properly into the webpage.

        The keyword here is “device-pixel-ratio”. If one web “pixel” == one physical pixel, then the device-pixel-ratio is 1.0. On high DPI displays, the ratio may be larger. On a retina display, that ratio is 2.0. On my Samsung Galaxy SII, it’s 1.5.

        The plugin banner space is 772px wide. If you’re displaying it on a device where the device-pixel-ratio is greater than about 1.5, then using the high-res image will give you more detail in the same space, and fit properly. On a retina display, you get all the detail, because 1 “web pixel” = 2 “physical pixels”.

        More info: http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density

    • Daniel Chatfield 4:15 pm on July 4, 2012 Permalink | Log in to Reply

      On my 3rd gen iPad I do not see retina graphics on the showcase page.

      • Samuel "Otto" Wood 4:17 pm on July 4, 2012 Permalink | Log in to Reply

        Refresh a couple times, or visit the main front page of the site first. It won’t recognize your device the first time, until the cookie gets set for you. This is to prevent us from having to waste a lot of bandwidth by serving low-res images and then converting them to high res images. Most people will get recognized before navigating deeper into a high-image area.

        • Matt 8:04 pm on July 4, 2012 Permalink | Log in to Reply

          It might not be that much of a waste.

        • Samuel "Otto" Wood 8:06 pm on July 4, 2012 Permalink | Log in to Reply

          For certain cases, I think I’ll probably look at optimizing the high-res images so that we can just use them always (if the filesizes are the same, then it doesn’t matter). Other cases can probably be converted to the CSS background approach, making JS unnecessary. I’m sure there’s further optimizations we can do.

      • Otto 8:18 pm on July 24, 2012 Permalink | Log in to Reply

        This should be fixed now, it’s using a CSS method instead.

    • Kaspars 8:00 pm on July 4, 2012 Permalink | Log in to Reply

      It would be nice if you posted all the server and WordPress related scripts that are used to accomplish this.

      • Samuel "Otto" Wood 8:04 pm on July 4, 2012 Permalink | Log in to Reply

        There’s not much to post, really. Adding this was just a matter of hacking in a few lines of code. The plugin SVN system is originally derived from the bbPress SVN Tracker plugin (https://bbpress.org/plugins/topic/svn-browser/) and the code that isn’t in there is just a bunch of customizations specific to the wp.org plugin repository and the theme for displaying it and such. Adding a line to make it find assets like these and use them when needed is just some additional add-on bits to that theme, nothing particularly special about it.

        • Kaspars 8:16 pm on July 4, 2012 Permalink | Log in to Reply

          Well, I see that you are setting a devicePixelRatio cookie, just like on Matt’s site, but the PHP thing which replaces the image URL must be something custom. Is that a cookie check on every request followed by “if_file_exists”?

        • Samuel "Otto" Wood 8:19 pm on July 4, 2012 Permalink | Log in to Reply

          Kaspars: Sort of. It is a cookie check at display time, but the file is only checked for during the scanning process which builds the plugin’s topic-page to begin with. I check for certain files and then add info about them to the topic-meta for the plugin’s topic. So it’s checking for a cookie, and then for the corresponding topicmeta. The cookie is site-wide, and used in a lot of places.

    • Kaspars 8:30 pm on July 4, 2012 Permalink | Log in to Reply

      OK, that means every page request has to be 100% dynamic and the complete WP stack has to be involved.

      What do you think of using nginx internal rewrites for resolving the correct image based on the cookie value?

      • Samuel "Otto" Wood 8:34 pm on July 4, 2012 Permalink | Log in to Reply

        I’m not trying to solve this as a generic problem, I’m solving it for WordPress.org. A generic solution such as you’re suggesting would very likely work though. However, you’d need a generic way to both produce and name the high-resolution images for them to be found and served programmatically. I’d also be concerned about naming and proxy-caching by other systems, you’d likely want to redirect browsers to alternate URLs in case they’re behind a caching system of some sort. Having the same URL return two different things depending on a cookie (or user-agent sniffing) is a recipe for problems.

        • Kaspars 8:40 pm on July 4, 2012 Permalink | Log in to Reply

          That explains it, and I completely agree.

          Out of curiosity, what are the average requests per second on WP.org and how many server are involved doing the PHP (and what is “X-nc: BYPASS luv 138”)?

        • Lloyd Dewolf 4:36 pm on July 5, 2012 Permalink | Log in to Reply

          BYPASS means that it’s bypassing WordPress(.com) “full html” cache, based on the information in your request (likely cookie or useragent).
          luv is the datacenter: Love Field Airport (DAL)
          138 relates to which of the static caching servers it would have HIT, I believe.

    • dartiss 11:57 am on July 5, 2012 Permalink | Log in to Reply

      If only I’d kept the originals for some of my banners πŸ˜‰ Oh well, Artiss Content Reveal has been updated, if anybody wants another example to try!

    • SK 4:26 pm on July 10, 2012 Permalink | Log in to Reply

      Otto — I was a bit confused which approach you took provider higher resolution images for devices with high DPI displays.

      1) Are you performing user-agent detection in PHP and rewriting the the URLs in HTML from something such as image.jpg to image-high.jpg?


      2) Are you replacing the images with JS after the page loads? I’ve seen popular snippets such as http://retinajs.com/ making their rounds on Hacker News.

      Feedback would be awesome, thanks!

      • Otto 8:20 pm on July 24, 2012 Permalink | Log in to Reply

        For the vast majority of cases, I’m using pure CSS now. For edge cases, there’s a cookie that gets set with your device pixel ratio which we can use on the server side of things to determine which image to show you.

    • Matt Mullenweg 8:40 pm on July 12, 2012 Permalink | Log in to Reply

      The Jetpack plugin is now updated: https://wordpress.org/extend/plugins/jetpack/

compose new post
next post/next comment
previous post/previous comment
show/hide comments
go to top
go to login
show/hide help
shift + esc
Skip to toolbar