CSS for high-resolution images on mobile and retina displays - html

My website images look blurry for users with retina displays. (For example, on the Retina MacBook Pro).
How do I serve high-resolution images to visitors with retina displays, but standard-sized images to everyone else, while keeping the image the same apparent size?

In your HTML, create a <div> like so:
<div class="ninjas-image"></div>
And in your CSS, add:
.ninjas-image {
background-image: url('ninja-devices.png');
width: 410px;
height: 450px;
}
#media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) {
.ninjas-image {
background-image: url('ninja-devices#2x.png');
background-size: 410px 450px;
}
}
The magic here is in the CSS #media query. We have a double-sized image (ninja-devices#2x.png) that we sub-in when the device reports a ‘device pixel ratio’ of 1.5 (144 dpi) or more. Doing it this way allows you to save on bandwidth by delivering the original, smaller image to non-retina devices, and of course it looks great on retina devices.
Note:
This answer was updated in 2016 to reflect best-practice. min-device-pixel-ratio did not make it in to the standard. Instead, min-resolution was added to the standard, but desktop and mobile Safari don't support it at the time of writing, (thus the -webkit-min-device-pixel-ratio fallback). You can check the latest information at: http://caniuse.com/#feat=css-media-resolution.

We've been using the following to handle multiple cases where the ratio is 1.5 or higher - this takes more devices and browsers into account:
#media only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (-o-min-device-pixel-ratio: 3/2),
only screen and (min--moz-device-pixel-ratio: 1.5),
only screen and (min-device-pixel-ratio: 1.5) {
We have our entire site Retina enabled: http://www.embraceware.com/

Related

Problem with responsive IMG tag: browser picking wrong size order

First I would like to mention that I did read and check all the articles I could find here regarding this problem, but unfortunately none of them are clear enough or fix the issue for me.
There is no clear explanation + solution to this problem, and it's a really well sought after problem with images.
Using <picture> tags I can achieve the purpose and the browser will
load the correct image based on the max-width media specification.
Using <img /> tag the browser picks randomly regardless of the sizes
or order of sizes specified.
In this scenario I am required to use the <img />. Consider the following code for a simple header image:
<img
width="1400px" height="230px"
class="page-header-image" alt=""
src="/wp-content/uploads/z8poevCA-1.jpeg"
srcset="/wp-content/uploads/z8poevCA-2.jpeg 1200w,
/wp-content/uploads/z8poevCA-3.jpeg 992w,
/wp-content/uploads/z8poevCA-4.jpeg 768w,
/wp-content/uploads/z8poevCA-5.jpeg 576w,
/wp-content/uploads/z8poevCA-6.jpeg 230w"
sizes="(min-width: 1200px) 1200px, (min-width: 992px) 992px, (min-width: 768px) 768px, (min-width: 576px) 576px, (min-width: 230px), 230px" />
The above for me translates as:
Default image size in src is width="1400px" height="230px" load: z8poevCA-1.jpeg
XX-Large devices (larger desktops, 1400px and up) load: z8poevCA-1.jpeg
X-Large devices (large desktops, 1200px and up) load: z8poevCA-2.jpeg
Large devices (desktops, 992px and up) load: z8poevCA-3.jpeg
Medium devices (tablets, 768px and up) load: z8poevCA-4.jpeg
Small devices (landscape phones, 576px and up) load: z8poevCA-5.jpeg
X-Small devices (portrait phones, less than 576px) load: z8poevCA-6.jpeg
However, the browser will pick for example on a mobile screen of 400px the 1200w version of the image; which is wrong. The above works perfectly with <picture> tags, so I doubt the sizes as "wrong" - unless the <img /> tags work differently.
The above is just an example, as I have tried many different combinations of sizes with the <img /> tag; all went wrong. I also tried: https://responsivebreakpoints.com/ and whilst the tool is "cool" it's using <picture> and it's missing the sizes.
I would also like to mention that the document is using the meta tag:
<meta name="viewport" content="width=device-width, initial-scale=1" />
And here is the CSS (if needed):
.page-header-image, .page-header-image img {
width: 100%;
height: 100%!important;
-o-object-fit: cover;
object-fit: cover;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
Demo:
<img
width="1400px" height="230px"
class="page-header-image" alt=""
src="https://via.placeholder.com/1400x230"
srcset="https://via.placeholder.com/1200x200 1200w,
https://via.placeholder.com/992x130 992w,
https://via.placeholder.com/768x100 768w,
https://via.placeholder.com/576x90 576w,
https://via.placeholder.com/230x90 230w"
sizes="(min-width: 1200px) 1200px, (min-width: 992px) 992px, (min-width: 768px) 768px, (min-width: 576px) 576px, (min-width: 230px), 230px" />
Please shed some light onto this matter as this will help many users having this problem.
Thanks
Using the given snippet in Firefox on Windows 10 the 'correct' size of image is shown each time for me (Windows 10).
However, on Chrome/Edge the larger image (1200px) was shown each time, however small I made the window (or the img element width).
This seems to be a cacheing issue.
If I clear the Chrome browser's cache and run the snippet on a window that is already small the correct image is shown and as I increase the window width the correct images are successively shown until it reaches the maximum one of 1200px.
If I then rerun the same experiment, the 1200px image is shown straight away. Somehow the browser is saying 'I've already got an image that is at least as large as the one wanted so I'll show that rather than get a smaller one'.
Hopefully someone can find a more formal description of what is going on.
Basically, your code is fine. The system (at least Chrome/Edge on W10) will only bother to go and fetch another image if it feels it has to, so the user isn't unnecessarily using their network allowance. I don't know if there's a way of telling other browsers like FF to do the same.

Viewport meta tag required when using vh/vw CSS units?

I have designed a responsive website which uses vh and vw scales rather than pixel sizes throughout the CSS, including font-size properties. I know the site views perfectly fine on mobile/tablet screens as well as PCs and laptops as I have tested it out. Everything is readable with good character sizing and all elements (buttons etc. are sized and spaced well for good UX), and if needed, pinch zooming works too.
The issue I am having is that Google Search Console is saying that a viewport meta tag is needed.
Why would that be?
Looking here for previous Q&As on this subject, as pointed out in the highest upvoted answer, the issue with CSS Web page not responsive when using vh and vw was because there was no max-width property in the CSS
The answer from #Sheriffderek to Viewport meta tags vs Media Queries? pointed out that:
You'll want a metaviewport tag (always)
My CSS media queries are as so..
/*****************************************************
Apple iPhones
Samsung Galaxy Mobile Phones
in Landscape
*****************************************************/
#media (-webkit-min-device-pixel-ratio: 1.1) and (orientation: landscape) {
}
/*****************************************************
Kindle Fire HDX,
iPad and iPad Pro
in Landscape
*****************************************************/
#media (-webkit-device-pixel-ratio: 2) and (min-width: 1000px) and (orientation: landscape) {
}
/****************************************************
Tablets and Mobile Phones
in portrait
****************************************************/
#media (orientation: portrait) {
}
/****************************************************
Apple iPhones and
Samsung Galaxy Mobile Phones
in portrait
****************************************************/
#media (-webkit-min-device-pixel-ratio: 1.1) and (orientation: portrait) {
}
/*****************************************************
Kindle Fire HDX,
iPad and iPad Pro
in Portrait
*****************************************************/
#media (-webkit-device-pixel-ratio: 2) and (orientation: portrait) {
}
What is the deal here? Do I really need a viewport meta tag if responsiveness is already taken care of? If so, why?

CSS #media for distinguishing mobile and desktop devices

I tried setting two different styles for a website using #media. But it always loads the desktop view no matter if I use a phone or a computer.
/* desktop screen */
#media (min-width: 801px){
content desktop
}
/* mobile screen */
#media (max-width: 800px){
content mobile
}
What have I done wrong?
The actual answer to your question is: you're using width and device-width wrong. Change line #169 from:
#media (max-device-width: 800px){
to:
#media (max-width: 800px){
If you want to target phones specifically, it is a good idea to look at media queries used by popular frameworks such as bootstrap or foundation. You'll find that many target much smaller sizes such as 320px or 480px as opposed to 800px in your code.
The thing is CSS media queries distinguish features not devices. So you can try to figure out which features correspond to the device you want to refer to. In this site you have media queries for iPhones, iPads. So for example:
iPhone 6 in portrait & landscape:
#media only screen
and (min-device-width : 375px)
and (max-device-width : 667px) { /* STYLES GO HERE */}
These queries try to reduce the case to get to an specific device using its features. In this site you have a set of predefined queries for specific devices.
But notice that the difference between Desktop and Mobile might not be so obvious.
And don't forget to add meta in to <head></head>
<meta content="width=device-width" name="viewport" />
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0" />

How to handle the different resolution (Retina & HDs) in mobile device?

I'm having different CSS files for different layout (Phone & Tablet). Since I have added styling in tablet view based on the view I get on my Samsung Note 8 with resolution 1200x800.
But when I run this application on Samsung Galaxy tab750 with resolution 1920x1080, I get smaller layout with smaller fonts since I have adjusted the fonts and layout based on Note 8.
So I get the suggestion to add the another CSS file for handling this. Next, when our QA tried running the application on iPad (Retina Display 2048x1536), again the third CSS is even small in it.
In 2012, there was a single tablet with a 2,560x1,600 resolution. In 2013, there were at least six. I suspect we'll see even more in 2014 (http://ces.cnet.com/8301-35302_1-57615742/tablets-at-ces-2014-the-calm-before-the-storm/#ixzz2nhc1BlAw).
With respect of this post Responsive Web Design and high resolution displays (iPhone 4/5),
We would be using media queries for required resolutions,
/* Large desktop */
#media (min-width: 1200px) {
font-size: 18px;
}
/* Portrait tablet to landscape and desktop */
#media (min-width: 768px) and (max-width: 979px) {
font-size: 16px;
}
/* Landscape phone to portrait tablet */
#media (max-width: 767px) {
font-size: 14px;
}
/* Landscape phones and down */
#media (max-width: 480px) {
font-size: 12px;
}
So my concern is can we handle this scenario, without going on adding more and more CSS and media queries, if so please suggests.
There are a number of media-query based ways of detecting high-density/retina devices.
I personally tend to use this, which seems to capture the vast majority of devices:
#media screen and (-webkit-min-device-pixel-ratio: 2),
screen and (max--moz-device-pixel-ratio: 2),
screen and (min-device-pixel-ratio: 2) {}
Totally personal preference though!
Do bear in mind that - to the most part - 'high density' screens (rather than just high-resolution) report themselves as their non-HD resolution for the purpose of media queries.
For example: the Retina Apple iPads have an actual screen-resolution of 2,048 by 1,536, but still reports as 1,024 by 768px. Thus, the same screen-width/height media queries will capture the iPad 4 (retina) as the iPad 2 and - apart from being a little more blurry in the case of the older iPad - will look the same.
You can combine the media query I've included above with width/height to get a much more granular target on specifically-HD devices if you wish.
One very important exception to this is high-density display devices running Windows 8 Mobile which has a known bug with correctly reporting the viewport.

Twitter Bootstrap tablet dimension 1024 not 979 on responsive layout

I do not understand why Twitter Bootstrap is considering the tablet size from 768 to 979, and not from 768 to 1024 (iPad). The problem is that if a client requests a custom design for tablet, that tablet design will not be visible on iPad in landscape mode.
Also if I have a content with sidebar (span9 + span3), if the sidebar is "hidden-tablet", the content will not expand, in fact it will have the same size and I have to overwrite bootstraps span dimmensions to achieve the desired layout.
Am I doing something wrong?
1) I think the idea here is that in general if someone is requesting a page that is over 980px its more likely that its from a desktop computer than it is from an ipad. Also you could just make your page ipad AND web friendly for those widths :).
If you have to have a different design for landscape ipad and the web, an option would be to do write a bunch of custom css for when the screen is between 980 and 1024px.
#media (min-width 980px) and (max-width: 1024px) {
//my custom css for ipad landscape
}
2) You are doing it right. All .hidden-tablet does is set display: none;
#media (min-width: 768px) and (max-width: 979px) {
// ... some other code
.hidden-tablet {
display: none !important;
}
}
It does not do any other type of resizing, so thats on you to do with media queries.