How to distinguish between mobile and screen with CSS media query? - css

I read that most media queries use viewport width to determine whether your are on a phone, tablet or PC. I am building an image grid with 1000s of small thumbs in an endless grid. Each thumb is 125px and on my laptop (MacBook 13") I can easily fit 9-10 thumbs in one row - which gives a fine user experience. If I take the same code to a nexus 5, which has 1080px across I get 6-7 thumbs, which is a bad user experience. the nexus is 6-7 cm across and the MacBook is 25'ish cm - big difference.
My approach would be to detect whether the device is a mobile or pc and the scale the thumbs - big ones for mobile (say 250px) and small for pc (125px).
But how do I detect the device. If I use width I basically have to go with a min-width of 1100px to catch most new phones. I could also go with resolution, mobile phones generally have higher DPIs than PC/laptops.
Or do I have this completely wrong?
I am writing the app in React.

It's not that your Nexus 5 renders webpages at 1080px wide, it's that your site is not performing responsively to fit your phone screen, so it's rendering as a zoomed-out desktop site.
You need to add this viewport meta tag to your site's <head>:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
Once that's in, your Nexus 5 should render webpages at something closer to 400px wide, and you can base your media queries around that.
Here's how you'd make your thumbnails 125px wide for screens under 480px wide:
#media (max-width: 480px) {
img {
width: 125px;
}
}

Related

how come media query won't work for mobile device?

As you can see from the screen, I do have a media query CSS
#media only screen and (max-width: 600px) {
.block {
background-color: lightblue;
width: 100%;
margin-top: 20px;
}
}
But for mobile device with under 600px, the block won't able to display lightblue background; but resize with desktop browser works.
Why?
detail code with here: https://codepen.io/dotku/pen/VwZGKYV
The comment from #Reza works, that is add viewport meta.
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
I don't know what mobile device you're testing on, but I'm assuming you're not aware of the difference between device pixels and actual CSS pixels: CSS pixels are an abstraction over the real pixels in your device's specs to make webpages appear consistent on all the different device sizes.
Formula:
CSS pixels = Physical resolution / Device Pixel Ratio
The Device Pixel Ratio itself is determined by each browser on each device independently.
On my phone, your codepen works fine and displays blue. I recommend checking out this codepen, which will reveal your Device Pixel Ratio and logical resolution. Most likely your device has a CSS width larger than 600px.
On my phone, given codepen example works without meta tag (color change, meta tag is just for scaling, so this means that #media query is read properly).
Also, some new phones or phablets have virtual resolution 800px in portrait mode, so website should be tested on those devices.
If color doesn't change, try deleting Chrome cache on mobile phone: https://support.google.com/accounts/answer/32050?co=GENIE.Platform%3DAndroid&hl=en
I had the same problem two days ago, especially yesterday after Chrome was updated (seemed just to ignore any changes to #media queries, which showed properly on desktop in responsive mode).
After testing website with Firefox for Android (worked properly), and also with Chrome failing to reflect some changes to CSS outside #media query (background-color), it was obvious that Chrome didn't load changed CSS file from the server, but used some older locally cached version.
After deleting browsing cache, everything works as it should be (even after CSS file was changed a few times after this).

CSS mobile website - why so high values?

To fit my WP website for mobiles I use
#media screen and (max-device-width: 780px) {}
However, to fit everything properly I have to use giant values, like font-size: 4em;, header {height: 200px;} (when it's 100 on the desktop version). Is it normal?
The main problem is with Gallery plugin - by default thumbs have size e.g. 200x300, and on the mobile version they are really tiny!
Or maybe there is a better way to make a website mobile?
If I had to guess, I'd say you are not setting your viewport
<meta name="viewport" content="width=device-width, initial-scale=1"/>
Nowadays, most mobile phones have a very high dpi; for instance, the iphone 6 plus has a full 1080p display, so when you make something 100px tall, it is only 1/19 of the screen height.
By setting the viewport to the device-width, you are telling the browser to render the page using a more standard dpi (for instance, the iphone 6 would be something like 424x600ish). That way, all of your content automatically scales.

My 320px width adsense unit is too small on newer smart phones

I have a 320px x 50px adsense unit I am trying to display on an iPhone 6. (Or any mobile browser with a width more than 320px - iPhone 3Gs was 320px wide.) The ad unit is way too small.
I tried using CSS, media queries, and other things. No dice.
I tried using Google's Responsive ads. No dice.
I looked at a bunch of sites with the Google Chrome device mode and found a site that had a 320px wide add, but it was taking the full viewport width on an iPhone 6!
How can I get the ad to display on the full width of the page?
With all of the different device screen sizes, now there is a way to set the viewport size on mobile browsers.
<meta name="viewport" content="width=device-width">
This will scale the 320px width ad unit to fit the full width of the device.
More reading.
try this add it you your CSS
img
{
max-width:100%;
}
I think will work with you.

Viewport issue, zoomed in on ipad when using device width

I'm having an issue with how my site is being displayed on my ipad. I've tried to set the viewport to:
<meta name="viewport" content="width=device-width, initial-scale=1">
Which can be seen at http://erichschubert.com/viewport.html.
But it always results in my site appearing zoomed in and even when zooming out, the whole site is not visible.
As of now I have it running with:
<meta name="viewport" content="width=1024">
Which can be seen at http://erichschubert.com.
It appears fine, however, when the ipad is turned to landscape it zooms in and leaves a huge black sidebar on the right side.
The header on the site has a fixed position and is also not displaying properly when zoomed in. Is the issue simply that it is fixed? I would love to able to display the whole site in both portrait and landscape and also be able to zoom in uniformly.
Thank you so much for any help in advance.
The initial-scale=1 is only practical if you use it alongside media queries, so it accurately scales the page to fit the custom styles for that media query.
Changing it to width=1024 only forces a fixed page width, which is no use in your case.
The smoothest way to have a page scale without zooming issues is to use media queries, to allow it to resize depending on the screen size.
Most devices will re-assess the screen width when they detect a change in orientation, while others will simply zoom in to fit the portrait layout to the landscape view.
If you want to be sure, you could use:
#media only screen and (orientation:portrait) {
/* portrait stuff here */
}
and for landscape:
#media only screen and (orientation:landscape) {
/* landscape stuff here */
}
I wouldn't recommend being so specific as to target individual devices, it's a never-ending workload. 'iPad' used to mean 768px x 1024px, but now covers 2048px x 1536px too. There will always be new devices, but they will all be targetable via simple media queries.

Can I use max-device-width and device-width without device-pixel-ratio?

I have a mobile site which tests on any modern device. My viewport meta tag is:
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
The question:
Can I relay on viewport value (especially on width=device-width) and write media queries with out device-pixel-ratio values.
Code example:
I have a block which has different layout while screen width is smaller 400px.
Can I use with such viewport media query like this(1):
#media all and (max-width: 399px) {
/* some css code */
}
Or like this(2):
#media all and (max-device-width: 399px) {
/* some css code */
}
Or I must combine 1 or 2 with large part of device-pixel-ratio values(3) for every media query:
only screen and (-webkit-min-device-pixel-ratio: 2) and (max-width: 399px),
only screen and ( min--moz-device-pixel-ratio: 2) and (max-width: 399px),
only screen and ( -o-min-device-pixel-ratio: 2/1) and (max-width: 399px),
only screen and ( min-device-pixel-ratio: 2) and (max-width: 399px),
only screen and ( min-resolution: 192dpi) and (max-width: 399px),
only screen and ( min-resolution: 2dppx) and (max-width: 399px) {
/*some css code*/
}
And the second question:
In my mind string width=device-width must prevent the difference between css pixels and device pixels. Is last statement wrong?
Short answers:
You can just use the max-width or max-device-width queries alone. You've taken care of the rest with the meta tag.
Your second question not quite right: it doesn't really relate to device pixels. width=device-width just tells the device to use its default virtual pixel (CSS pixel) measurement.
Another note: the last example with the complex media query would only target high-resolution devices, which is probably not what you want in this example.
Explanation:
I'm going to refer to CSS pixels as virtual pixels, but I think we're talking about the same thing.
Virtual pixel measurement is the number the browser says is its pixel width. It relates directly to CSS pixels, but can be different from device pixels. For example, if I have an older iPhone with standard-resolution display, its virtual pixel width is 320. (This takes up 320 CSS pixels.) The display also has 320 actual pixels in its width, or 320 device pixels, so the device-pixel-ratio (the ratio of virtual pixels to device pixels) is 1.
If I upgrade to a newer iPhone with a high-resolution display, it still registers 320 virtual pixels, but it now has a device-pixel-ratio of 2, or 640 actual pixels in its width. That's why everything looks so clear--there are more pixels in the same space.
If I view a site on either one of those devices, the width looks the same because they have the same virtual pixel measurement. To my CSS, they're both 320 pixels wide. This is pretty straightforward, until some mobile browsers allow us to pinch and zoom to resize a web page. This resizing changes the virtual pixel width.
Some mobile browsers actually do this resizing automatically. So if I were to visit a site on my phone's browser that had a fixed 1000px width, my phone's browser might try to fit the full width of the site in the viewable window, which would make my virtual pixels come out to 1000 instead of 320. I'd be viewing a very, very small version of the site. This is a problem for responsive sites, because if my phone says it's got 1000 virtual pixels, it activates my 1000px media query rather than the correct 320px query.
width=device-width and initial-scale=1 disable this automatic resizing, so you know that if the browser's native virtual width is 320, that's what you'll get on initial load.
minimum-scale=1, maximum-scale=1, user-scalable=no disable the user's ability to pinch and zoom by hand. This can be annoying to some users, but it gives you a little more control of the final viewing experience.
device-pixel-ratio is used to measure the resolution of the device. It's often used to serve high-resolution images to high-resolution devices, since normal resolution images can look blurry on a high-resolution device. Usually people test to see whether the device-pixel-ratio is at or above 1.5 or 2 to determine a high-resolution device.

Resources