Is there a way that works for all browsers?
original answer
Yes.
window.screen.availHeight
window.screen.availWidth
update 2017-11-10
From Tsunamis in the comments:
To get the native resolution of i.e. a mobile device you have to multiply with the device pixel ratio: window.screen.width * window.devicePixelRatio and window.screen.height * window.devicePixelRatio. This will also work on desktops, which will have a ratio of 1.
And from Ben in another answer:
In vanilla JavaScript, this will give you the AVAILABLE width/height:
window.screen.availHeight
window.screen.availWidth
For the absolute width/height, use:
window.screen.height
window.screen.width
var width = screen.width;
var height = screen.height;
In vanilla JavaScript, this will give you the AVAILABLE width/height:
window.screen.availHeight
window.screen.availWidth
For the absolute width/height, use:
window.screen.height
window.screen.width
Both of the above can be written without the window prefix.
Like jQuery? This works in all browsers, but each browser gives different values.
$(window).width()
$(window).height()
You can also get the WINDOW width and height, avoiding browser toolbars and... (not just screen size).
To do this, use:
window.innerWidth and window.innerHeight properties. See it at w3schools.
In most cases it will be the best way, in example, to display a perfectly centred floating modal dialog. It allows you to calculate positions on window, no matter which resolution orientation or window size is using the browser.
Do you mean display resolution (eg 72 dots per inch) or pixel dimensions (browser window is currently 1000 x 800 pixels)?
Screen resolution enables you to know how thick a 10 pixel line will be in inches. Pixel dimensions tell you what percentage of the available screen height will be taken up by a 10 pixel wide horizontal line.
There's no way to know the display resolution just from Javascript since the computer itself usually doesn't know the actual dimensions of the screen, just the number of pixels. 72 dpi is the usual guess....
Note that there's a lot of confusion about display resolution, often people use the term instead of pixel resolution, but the two are quite different. See Wikipedia
Of course, you can also measure resolution in dots per cm. There is also the obscure subject of non-square dots. But I digress.
Using jQuery you can do:
$(window).width()
$(window).height()
Trying to get this on a mobile device requires a few more steps. screen.availWidth stays the same regardless of the orientation of the device.
Here is my solution for mobile:
function getOrientation(){
return Math.abs(window.orientation) - 90 == 0 ? "landscape" : "portrait";
};
function getMobileWidth(){
return getOrientation() == "landscape" ? screen.availHeight : screen.availWidth;
};
function getMobileHeight(){
return getOrientation() == "landscape" ? screen.availWidth : screen.availHeight;
};
See Get Monitor Screen Resolution with Javascript and the window.screen object
function getScreenWidth()
{
var de = document.body.parentNode;
var db = document.body;
if(window.opera)return db.clientWidth;
if (document.compatMode=='CSS1Compat') return de.clientWidth;
else return db.clientWidth;
}
just for future reference:
function getscreenresolution()
{
window.alert("Your screen resolution is: " + screen.height + 'x' + screen.width);
}
If you want to detect screen resolution, you might want to checkout the plugin res. It allows you to do the following:
var res = require('res')
res.dppx() // 1
res.dpi() // 96
res.dpcm() // 37.79527559055118
Here are some great resolution takeaways from Ryan Van Etten, the plugin's author:
2 unit sets exist and differ at a fixed scale: device units and CSS units.
Resolution is calculated as the number of dots that can fit along a particular CSS length.
Unit conversion: 1in = 2.54cm = 96px = 72pt
CSS has relative and absolute lengths. In normal zoom: 1em = 16px
dppx is equivalent to device-pixel-ratio.
devicePixelRatio definition differs by platform.
Media queries can target min-resolution. Use with care for speed.
Here's the source code for res, as of today:
!function(root, name, make) {
if (typeof module != 'undefined' && module.exports) module.exports = make()
else root[name] = make()
}(this, 'res', function() {
var one = {dpi: 96, dpcm: 96 / 2.54}
function ie() {
return Math.sqrt(screen.deviceXDPI * screen.deviceYDPI) / one.dpi
}
function dppx() {
// devicePixelRatio: Webkit (Chrome/Android/Safari), Opera (Presto 2.8+), FF 18+
return typeof window == 'undefined' ? 0 : +window.devicePixelRatio || ie() || 0
}
function dpcm() {
return dppx() * one.dpcm
}
function dpi() {
return dppx() * one.dpi
}
return {'dppx': dppx, 'dpi': dpi, 'dpcm': dpcm}
});
if you mean browser resolution then
window.innerWidth gives you the browser resolution
you can test with http://howbigismybrowser.com/
try changing your screen resolution by zoom in / out browser and check resolution size with http://howbigismybrowser.com/
Window.innerWidth should be same as screen resolution width
Easy steps to find screen resolution is:
Copy
`My screen resolution is: ${window.screen.width} * ${window.screen.height}`
paste in browser console
hit enter
This is part of a larger program which is handling a scrollbar on a <div> when modifying the height.
When logging the output of various values for moving the scrollbar, there's an issue occurring where values are being produced with decimal places, but only on Opera (version 44.0.2510.1449), and this is only happening on my friend's browser. On my own Opera (version 44.0.2510.1449) I do not encounter the same problem.
Though it's probably irrelevant, the purpose of the code is to find out where the scrollbar is in the div with id #mydiv and do something based on the result.
Similar code with changed variable names:
var myDivHeight = $('#mydiv').height();
$('#mydiv').height(myDivHeight + 50); //10 extra for padding
var scrollTop = $('#mydiv').scrollTop();
var scrollHeight = $('#mydiv').prop('scrollHeight');
console.log(scrollHeight + '-' + scrollTop + '=' + (scrollHeight - scrollTop));
console.log(myDivHeight + 60);
Note: 60 is due to the changes made to the page dynamically, so the div height has been changed. The result of the output should be that scrollHeight - scrollTop = myDivHeight + 60.
Here's my friend's console output on Opera (giving fractional scrollTop):
Here's my console output on Opera:
Here's the console output on Chrome:
Here's the console output from Firefox:
I can't find anyone else reporting this. Has this been reported or seen by anyone else? Is there any way to overcome this?
Thank you.
It turns out that taking the time to ask the question helped me answer it on my own.
First of all, to overcome the problem, it's a case of using Math.round(scrollTop.value).
The specification for scrollTop shows it is a unrestricted double data type so Opera is handling this within spec. Reference: https://drafts.csswg.org/cssom-view/#dom-element-scrolltop
An issue where this came up in jQuery before the type was changed from integer to Number: https://github.com/jquery/api.jquery.com/issues/608
I'm try to get the browser viewport size.
When the page initially loads (in jQuery(function() { .. });) , both these show the correct value (eg: 560):
console.log($(window).height());
console.log(document.documentElement.clientHeight);
But later when I do the same thing, it shows the height of the whole docoument (eg: 11675).
There's a lot of HTML and JS and it would take a while to figure out what's going on, I was just wondering, did anyone see anything like this, if so, what can cause it and how can I get the correct size of the viewport? All google hits show that's the correct way to retrieve the value.
Note: I'm using chrome.
I recently bumped into the same problem in one of my projects. I didn't have time to dig and isolate this weird bug, and I ended up using this function (adapted from this answer) to correctly get the viewport dimensions :
var getViewportSize = (function(){
var w = window,
d = document,
e = d.documentElement,
g = d.getElementsByTagName('body')[0];
return function(){
return {
w : Math.max(w.innerWidth || e.clientWidth || g.clientWidth, app.config.minWidth),
h : Math.max(w.innerHeight|| e.clientHeight|| g.clientHeight, app.config.minHeight)
};
}
})();
From what I've tested, jQuery returned the incorrect size when the console or some other browser extension/toolbar was occupying some of the viewport space.
Hope this helps, but I'm also curious and trying to figure this one out, because it's hard to think that a mature lib such as jQuery 2.0 has these kind of bugs.
How do I get in Internet Explorer values equivalent to: window.screenX and window.screenY in Firefox ?
I've seen some "solution": window.screenLeft and window.screenTop but it is not correct. These properties give inner coordinates.
I move a window and I need values to use with window.moveTo() to restore the original location.
var saveLeft = window.screenLeft;
var saveTop = window.screenTop;
window.moveTo(saveLeft, saveTop);
var savePos = [
saveLeft + (saveLeft - window.screenLeft),
saveTop + (saveTop - window.screenTop)
];
Seems to work
Equivalent properties don't appear to exist for Internet Explorer windows. Have you seen the window.resizeBy(w, h) method? Using that you could grow by a specific amount and then shrink back down using negative values (or vice versa):
window.resizeBy(300, 300); // expand window by 300x300 pixels
window.setTimeout(function ()
{
window.resizeBy(-300, -300); // back to original size
}, 10000);
There are years since i did any MSIE programming, but i roughly remember using something like this
save screenLeft and Top as window postion (this is wrong but read on)
when restoring the position, window.moveTo(saved position)
(current screenLeft > saved Left) window.moveBy(-1,0)
the same for y position
the idea is that we place the window in a wrong position first and then correct it step by step
I'm working on a kind of unique app which needs to generate images at specific resolutions according to the device they are displayed on. So the output is different on a regular Windows browser (96ppi), iPhone (163ppi), Android G1 (180ppi), and other devices. I'm wondering if there's a way to detect this automatically.
My initial research seems to say no. The only suggestion I've seen is to make an element whose width is specified as "1in" in CSS, then check its offsetWidth (see also How to access screen display’s DPI settings via javascript?). Makes sense, but iPhone is lying to me with that technique, saying it's 96ppi.
Another approach might be to get the dimensions of the display in inches and then divide by the width in pixels, but I'm not sure how to do that either.
<div id='testdiv' style='height: 1in; left: -100%; position: absolute; top: -100%; width: 1in;'></div>
<script type='text/javascript'>
var devicePixelRatio = window.devicePixelRatio || 1;
dpi_x = document.getElementById('testdiv').offsetWidth * devicePixelRatio;
dpi_y = document.getElementById('testdiv').offsetHeight * devicePixelRatio;
console.log(dpi_x, dpi_y);
</script>
grabbed from here http://www.infobyip.com/detectmonitordpi.php. Works on mobile devices! (android 4.2.2 tested)
I came up with a way that doesn't require the DOM... at all
The DOM can be messy, requiring you to append stuff to the body without knowing what stuff is going on with width: x !important in your stylesheet. You would also have to wait for the DOM to be ready to use...
/**
* Binary search for a max value without knowing the exact value, only that it can be under or over
* It dose not test every number but instead looks for 1,2,4,8,16,32,64,128,96,95 to figure out that
* you thought about #96 from 0-infinity
*
* #example findFirstPositive(x => matchMedia(`(max-resolution: ${x}dpi)`).matches)
* #author Jimmy Wärting
* #see {#link https://stackoverflow.com/a/35941703/1008999}
* #param {function} fn The function to run the test on (should return truthy or falsy values)
* #param {number} start=1 Where to start looking from
* #param {function} _ (private)
* #returns {number} Intenger
*/
function findFirstPositive (f,b=1,d=(e,g,c)=>g<e?-1:0<f(c=e+g>>>1)?c==e||0>=f(c-1)?c:d(e,c-1):d(c+1,g)) {
for (;0>=f(b);b<<=1);return d(b>>>1,b)|0
}
var dpi = findFirstPositive(x => matchMedia(`(max-resolution: ${x}dpi)`).matches)
console.log(dpi)
There is the resolution CSS media query — it allows you to limit CSS styles to specific resolutions:
http://www.w3.org/TR/css3-mediaqueries/#resolution
However, it’s only supported by Firefox 3.5 and above, Opera 9 and above, and IE 9. Other browsers won’t apply your resolution-specific styles at all (although I haven’t checked non-desktop browsers).
Here is what works for me (but didn't test it on mobile phones):
<body><div id="ppitest" style="width:1in;visible:hidden;padding:0px"></div></body>
Then I put in the .js: screenPPI = document.getElementById('ppitest').offsetWidth;
This got me 96, which corresponds to my system's ppi.
DPI is by definition tied to the physical size of the display. So you won't be able to have the real DPI without knowing exactly the hardware behind.
Modern OSes agreed on a common value in order to have compatible displays: 96 dpi. That's a shame but that's a fact.
You will have to rely on sniffing in order to be able to guess the real screen size needed to compute the resolution (DPI = PixelSize / ScreenSize).
I also needed to display the same image at the same size at different screen dpi but only for Windows IE. I used:
<img src="image.jpg" style="
height:expression(scale(438, 192));
width:expression(scale(270, 192))" />
function scale(x, dpi) {
// dpi is for orignal dimensions of the image
return x * screen.deviceXDPI/dpi;
}
In this case the original image width/height are 270 and 438 and the image was developed on 192dpi screen. screen.deviceXDPI is not defined in Chrome and the scale function would need to be updated to support browsers other than IE
The reply from #Endless is pretty good, but not readable at all,
this is a similar approche with fixed min/max (it should be good ones)
var dpi = (function () {
for (var i = 56; i < 2000; i++) {
if (matchMedia("(max-resolution: " + i + "dpi)").matches === true) {
return i;
}
}
return i;
})();
matchMedia is now well supported and should give good result, see http://caniuse.com/#feat=matchmedia
Be careful the browser won't give you the exact screen dpi but only an approximation
function getPPI(){
// create an empty element
var div = document.createElement("div");
// give it an absolute size of one inch
div.style.width="1in";
// append it to the body
var body = document.getElementsByTagName("body")[0];
body.appendChild(div);
// read the computed width
var ppi = document.defaultView.getComputedStyle(div, null).getPropertyValue('width');
// remove it again
body.removeChild(div);
// and return the value
return parseFloat(ppi);
}
(From VodaFone)
Reading through all these responses was quite frustrating, when the only correct answer is: No, it is not possible to detect the DPI from JavaScript/CSS. Often, the operating system itself does not even know the DPI of the connected screens (and reports it as 96 dpi, which I suspect might be the reason why many people seem to believe that their method of detecting DPI in JavaScript is accurate). Also, when multiple screens are connected to a device forming a unified display, the viewport and even a single DOM element can span multiple screens with different DPIs, which would make these calculations quite challenging.
Most of the methods described in the other answers will almost always result in an output of 96 dpi, even though most screens nowadays have a higher DPI. For example, the screen of my ThinkPad T14 has 157 dpi, according to this calculator, but all the methods described here and my operating system tell me that it has 96 dpi.
Your idea of assigning a CSS width of 1in to a DOM element does not work. It seems that a CSS inch is defined as 96 CSS pixels. By my understanding, a CSS pixel is defined as a pixel multiplied by the devicePixelRatio, which traditionally is 1, but can be higher or lower depending on the zoom level configured in the graphical interface of the operating system and in the browser.
It seems that the approach of using resolution media queries produces at least some results on a few devices, but they are often still off by a factor of more than 2. Still, on most devices this approach also results in a value of 96 dpi.
I think your best approach is to combine the suggestion of the "sniffer" image with a matrix of known DPIs for devices (via user agent and other methods). It won't be exact and will be a pain to maintain, but without knowing more about the app you're trying to make that's the best suggestion I can offer.
Can't you do anything else? For instance, if you are generating an image to be recognized by a camera (i.e. you run your program, swipe your cellphone across a camera, magic happens), can't you use something size-independent?
If this is an application to be deployed in controlled environments, can you provide a calibration utility? (you could make something simple like print business cards with a small ruler in it, use it during the calibration process).
I just found this link: http://dpi.lv/. Basically it is a webtool to discover the client device resolution, dpi, and screen size.
I visited on my computer and mobile phone and it provides the correct resolution and DPI for me. There is a github repo for it, so you can see how it works.
Generate a list of known DPI:
https://stackoverflow.com/a/6793227
Detect the exact device. Using something like:
navigator.userAgent.toLowerCase();
For example, when detecting mobile:
window.isMobile=/iphone|ipod|ipad|android|blackberry|opera mini|opera mobi|skyfire|maemo|windows phone|palm|iemobile|symbian|symbianos|fennec/i.test(navigator.userAgent.toLowerCase());
And profit!
Readable code from #Endless reply:
const dpi = (function () {
let i = 1;
while ( !hasMatch(i) ) i *= 2;
function getValue(start, end) {
if (start > end) return -1;
let average = (start + end) / 2;
if ( hasMatch(average) ) {
if ( start == average || !hasMatch(average - 1) ) {
return average;
} else {
return getValue(start, average - 1);
}
} else {
return getValue(average + 1, end);
}
}
function hasMatch(x) {
return matchMedia(`(max-resolution: ${x}dpi)`).matches;
}
return getValue(i / 2, i) | 0;
})();
Maybe I'm a little bit steering off this topic...
I was working on a html canvas project, which was intended to provide a drawing canvas for people to draw lines on. I wanted to set canvas's size to 198x280mm which is fit for A4 printing.
So I started to search for a resolution to convert 'mm' to 'px' and to display the canvas suitably on both PC and mobile.
I tried solution from #Endless ,code as:
const canvas = document.getElementById("canvas");
function findFirstPositive(b, a, i, c) {
c=(d,e)=>e>=d?(a=d+(e-d)/2,0<b(a)&&(a==d||0>=b(a-1))?a:0>=b(a)?c(a+1,e):c(d,a-1)):-1
for (i = 1; 0 >= b(i);) i *= 2
return c(i / 2, i)|0
}
const dpi = findFirstPositive(x => matchMedia(`(max-resolution: ${x}dpi)`).matches)
let w = 198 * dpi / 25.4;
let h = 280 * dpi / 25.4;
canvas.width = w;
canvas.height = h;
It worked well on PC browser, showing dpi=96 and size was 748x1058 px;work well on PC
However turned to mobile devices, it was much larger than I expected: size: 1902x2689 px.can't work on mobile
After searching for keywords like devicePixelRatio, I suddenly realize that, I don't actually need to show real A4 size on mobile screen (under which situation it's actually hard to use), I just need the canvas's size fit for printing, so I simply set the size to:
let [w,h] = [748,1058];
canvas.width = w;
canvas.height = h;
...and it is well printed:well printed