These days there's a big difference between pixels and points (CSS pixels, DIPS). On my particular computer its the same, but on retina macs and a lot of phones, there's 4 or 8 pixels per point. http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html
That is, the “pixels” that are used in CSS declarations such as width: 300px or font-size: 14px,have nothing to do with the actual pixel density of the device, or even with the rumoured upcoming intermediate layer. They’re essentially an abstract construct created specifically for us web developers.
I want to get the screen resolution (the real screen resolution, you get it by now), and then serve an image scaled to maximally fill the screen. This means no need to get 2000x2000 pixels images on mobile devices, while still getting good resolutions on a large mac.
Hover, when using screen.height it returns CSS pixels not the screen resolution, meaning a retina mac will get an image that is half the size of the screen, resulting in pixelation. Any way to get the actual screen resolution, or the pixels-to-points ratio in javascript?
This will give you the actual screen height, regardless of pixel density which is altered by including the viewport tag...
screen.height * window.devicePixelRatio
Macs with retina renders pages in 2x scale, and so screen.height returns actual height divided by 2. See answers here
Related
I was having a hard time figuring out how to phrase this. Sorry if this is a noob question, I'm new to responsive design and mobile web design in general.
My phone (Galaxy s10e) will render my webpage as if it's 360 pixels wide, with all elements positioned appropriately based on this width. I have several image tags on the site that are the same width. I was using src images that are 360px wide, and this looks fine on desktop because it is actually rendering my images at 360px, but on mobile the images alone appear to be rendering at a much higher resolution, causing it to look terrible due to upscaling.
If someone could explain to me what is happening here it would really help, since I can't find information on this specific behavior. Some questions I have:
Is the browser choosing to position the elements based on a 360px width while rendering the actual content at the screen's resolution?
How do I account for this in my design? I considered rendering the images at the higher resolution and then having the page dynamically scale those images down (so even though the actual div is 360px, the browser can use the 'extra space' allotted by max-width to render the image at a higher resolution), but I want the images to remain 360px wide on desktop, not the higher max-width for mobile rendering.
Where can I learn all about this behavior so I know how to tackle responsive image scaling in the future?
Thank you for your time. Let me know if you have any other questions. I'm using ReactJS to develop the site.
OK so in a nutshell pixels are relative sizes. One pixel is not literally one pixel on your phone.
What happens is PPI kicks in and basically zooms in to make things readable.
Because if you actually tried to view 360px on a phone with that pixel density you'd see nothing really.
So lets look at some phone specs:
6.1 INCH
5.90 x 2.77 x 0.31 INCH
Resolution 1440 x 3040 PX ~ 550 PIXELS PER INCH
Viewport 360 x 760 PX 138 PIXELS PER INCH
Now the viewport is what you actually see on screen. in this case it give you a pixel ratio of like 4. So that means your phone has a resolution 4 times that of it's viewport.
so for a web app where a div is set to 200px wide it will display 200px as you'd expect it based on the viewport but this div is actually 800px wide relative to your phones resolution.
Now pictures don't need this limitation. Whats the point in a high res display if your pictures only display 200px with a pixel density one fourth of your screens capability.
So a picture lives in a dual reality on your phone. It has a box size which is the size of the image relative to your viewport but the image itself inside the box lives within your resolution relative to your devices total screen pixels.
So when you have and image that's 200px in the viewport its display resolution is actually 800px. So when you put a picture that's only 200px and have it on a screen that does viewport scaling which nowadays is pretty much everything you're effectively stretching that image to four times its actual size. or what ever the screen pixel density ratio to viewport is. AKA it looks like crap.
And to answer your needs on this I'm just going to direct you here to MOZ who will go over the whys and how's as well as show you what to do to combat this.
Moz on Viewports
Combating element position is pretty easy you just use :
<meta name="viewport" content="width=device-width, initial-scale=1" />
In your <head>,
Moz on Image Scaling
I have set a fixed height for a div, let's say:
div.box {
height: 250px;
}
Using a tool (Meazure) which measures the pixels of the screen, I've noticed that on my desktop PC, which has a monitor of 1680x1050 pixels resolution, the pixels of the box are 250px (the right value); however, in my laptop, which has a 1920x1280 resolution display, the pixels measured using Meazure are different! It shows 539 pixels...
The same thing happens for offset values given in pixels... I notice different behaviours among different screens and devices (on my smartphone this effect is much more amplified...)
How can I set a "fixed" value which will appear the same for every device?
(Note: I don't want to use 100% for the width, since I want the box to have a fixed value even after resizing the window).
How can I set a "fixed" value which will appear the same for every device?
That's the thing, though: a "fixed" pixel value wouldn't appear the same on every device, because high-density screens are a thing that exists.
That 250px box that looks fine on a 72ppi screen would be itsy-bitsy on a high density 300ppi screen (specifically it'd be 24% of the intended size.) Browsers compensate for this using the device pixel ratio to adjust the specified pixel value to an appropriate size for that screen on that device. (Your 'meazure' tool doesn't appear to be taking this pixel ratio into account, which would seem to rather limit its usefulness, as it will only give accurate results on a traditional low-density screen.)
In theory you could undo this by multiplying the size of an element by the inverse of the current devicePixelRatio, but the result would be the opposite of what you want: the elements would have the same number of physical pixels, but would look completely different sizes on each device.
In practice it's mostly safe to ignore that this is happening at all and trust the browser to adjust your specified sizes correctly. (Take measurements using a density-aware tool, or the browser's own developer tools.) The only case where you really need to take this into account is if you include high-resolution bitmap images for use on higher-density screens; in those cases you'd use #media queries to determine which image the browser should use, such as
#media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
/* 2x-res images here */
}
/* low-res images here */
(the -webkit prefixed value is, of course, vendor-specific; resolution is the not-yet-universally-supported standard.)
I would first suggest to first check actual CSS properties. Right button -> inspect element and to see if on your PC and laptop div.box height is actually set to 250px
Maybe due to different resolutions, different styles are being applied.
If you have a www. page to look at, post it in comments
So basically, I created an Android WebView, in a 720 x 1280 screen. However when I evaluate screen.width and screen.height, the response is 360 and 640.
I understand that this may be partly so that content is displayed on a readable way, but, when I tried to set a static width to the WebView, like 1000px x 1000px, the Javascript still evaluates the same.
Is there a way to disable this, so that the content looks same as it would on a desktop screen, and the screen.width and screen.height return the real phone resolution or the one I manually set in the XML.
A Crosswalk (based in chromium) solution is also acceptable, even if it includes changing the source code, if WebView solution is not possible.
If I understand you right, you want to show websites in desktop mode, not in mobile mode. To achieve this you can use this custom subclass of WebView: https://github.com/delight-im/Android-AdvancedWebView
It has a method setDesktopMode(true) that will do what you want.
This maybe be due to the pixel ratio of the device.
see this thread for a detailed explanation
Note that different android screens will have different ratios depending on their resolutions. My experience is with iphone / ipad; and my solution was to detect the pixel ratio and use that as a multiplier for positioning all elements.
Also If feasible, I recommend positioning based on a multiplier rather than a fixed value. For example:
x = 0.5 * screen.width * xPixelRatio
will give you a relative position at 50% (i.e the middle) of the screen. By positioning elements in this way as long as your aspect ratio is the same the elements will always stretch to fit properly, and you can adjust for different aspect ratios by changing the xPixelRatio & yPixelRatio variables.
I'm trying to set an image to be the full height of a screen on a phoneGap app. Currently, I'm using the following code to determine the screen "dimensions" and I'm using javascript to set the image resolution to those dims.
$('.fullPageImage').height(window.screen.availHeight);
This produces the desired result on the iPhone 6 (retina display) as well as rendering on my laptop. The problem is when I try it on my Galaxy Note-3, the image is HUGE, and here's why: When I console.log(window.screen.availHeight); the Note seems to think its height is 1920 pixels - whereas my iPhone 6 only has 647 (and it's a retina display), so I know 1920 is not the actual number of pixels (or is it?). I looked into how the device is obtaining its window.screen.availHeight and found out there's this variable called window.devicePixelRatio and its value on the Note 3 is 3. I figured the viewport dimension on the Note 3 is 360x640, so the 3 for devicePixelRatio makes sense. Now, what puzzles me is that when I console.log(window.devicePixelRatio); on my iPhone 6, the result is 2. I tried setting the image height to 1/3 of the "availHeight" value using this code:
$('.fullPageImage').height(window.screen.availHeight/window.devicePixelRatio);
and it works great on the Note 3 (since it shrinks the image height down to 360 - as it should be), but on the iPhone, shrinking the image down to 324 (or something close) means the image onlly appears over half the page height.
My question is, instead of dividing by the devicePixelRatio, is there another variable I can obtain from the device in order to determine the ratio by which to shrink the image? The resulting ratio should 1 on the iPhone and 1/3 on the Note 3 in order for the image to correctly appear over the full height.
Thank you so much in advance!
Rather than explicitly setting the height, you should have the capability to use viewport units with CSS... so you could do something like the following:
$('.fullPageImage').css("height", "100vh");
That would set the height to 100% vertical height of the viewport, whatever that value might be.
You might also want to look into adding a <meta name="viewport" content="width=device-width, initial-scale=1"> tag to your header.
I'd like to categorize devices by screen width in client-side JavaScript code
All devices fitting to one hand (7" less) to mobile category
Treat other devices as desktop devices
Fallback: Treat devices which do not support necessary APIs as mobile devices
Question
Which related JavaScript and CSS APIs I could use to detect the screen physical dimensions? Please note that these APIs do not need to be necessarily supported in older browsers, as there is safe fallback. Also, I don't care about legacy desktop browsers either.
Firefox support is optional - if they have compatible APIs already.
Please note that this is about physical dimensions, not pixel dimensions.
There's no direct way to get the screen size in inches, but there are workarounds that use screen density to find the device size. It's not perfect, but you don't really need to know the exact size to 5 significant figures. Also, it is normally better to simply use pixel values, IMO.
HTML
Make a test div, and then see the number of pixels displayed to get the pixel density, then use that in your calculations. This should work, assuming that your browser/OS are configured properly (it didn't work in the this question but it was within half an inch on my computer).
EDIT: This is 100% wrong. The inch/cm measurements in CSS aren't based on an actual physical measurement. They're based on an exact conversion (1 inch = 96 px, 1 cm = 37.8 px). My apologies.
CSS
The best way to detect physical screen size is to use CSS media queries. The min-resolution and max-resolution queries can be used to get the resolution in either dpi or dpcm:
#media (min-resolution: 300dpi){
// styles
}
Combining it with the min-device-width and max-device-width queries, you get something like:
#media (resolution: 326dpi) and (device-width: 640) and (device-height: 960){
// iPhone
}
The problem is that if you want to target 7 inch devices, you'd have to have many resolutions and corresponding widths that go together, which could get complicated.
For more information:
MDN- CSS Media Queries
MDN- Resolution
"Mobifying" Guide
High DPI Images for Variable Pixel Densities (Somewhat Related)
Javascript
You can use window.devicePixelRatio to determine the screen density. From Android's WebView Reference:
The window.devicePixelRatio DOM property. The value of this property specifies the default scaling factor used for the current device. For example, if the value of window.devicePixelRatio is "1.0", then the device is considered a medium density (mdpi) device and default scaling is not applied to the web page; if the value is "1.5", then the device is considered a high density device (hdpi) and the page content is scaled 1.5x; if the value is "0.75", then the device is considered a low density device (ldpi) and the content is scaled 0.75x.
Then using this, you calculate the physical size by dividing this by the total number of pixels, which can be calculated with window.screen.width and window.screen.height (Don't use window.screen.availHeight or window.screen.availWidth because these only detect the available height).
For more information:
Android Webview Reference
MDN - Screen.width
MDN - Screen.height
devicePixelRatio Explanation
better to use CSS
#media screen and (max-width: 672px){
//your code for mobile category
}
#media screen and (min-width: 672px){
//your code for desktop category
}