I want to provide my visitors the ability to see images in high quality, is there any way I can detect the window size?
Or better yet, the viewport size of the browser with JavaScript? See green area here:
I want to provide my visitors the ability to see images in high quality, is there any way I can detect the window size?
Or better yet, the viewport size of the browser with JavaScript? See green area here:
@media (width)
and @media (height)
values let vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)
let vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0)
window.innerWidth
and window.innerHeight
@media (width)
and @media (height)
which include scrollbarsinitial-scale
and zoom variations may cause mobile values to wrongly scale down to what PPK calls the visual viewport and be smaller than the @media
valuesundefined
in IE8-document.documentElement.clientWidth
and .clientHeight
@media (width)
and @media (height)
when there is no scrollbarjQuery(window).width()
which jQuery calls the browser viewportmatchMedia
to obtain precise dimensions in any unitclientWidth
/ clientHeight
is a no-go in IE9 on mobile. Can you please clarify on that? Excellent answer by the way! Thanks! –
Koehler $
with verge
. If you want to integrate into jQuery then do jQuery.extend(verge)
. See: verge.airve.com/#static –
Gerta <!DOCTYPE html>
at the top of the page in order for the code to work. –
Eliaseliason window.innerWidth
? I'm trying to calculate the scrollbar width to solve / simplify https://mcmap.net/q/54302/-position-displacement-when-toggling-several-overflow-y-elements/89771. –
Basel document.documentElement.clientHeight
and window.innerHeight
have the same value, wich is even different from window.screen.height
window.screen.availHeight
when adressbar is hidden because of digital controls (tested on nexus 5 with android lollipop ) –
Skive document.documentElement.clientHeight
returns the page height, while window.innerHeight
returns the viewport height. Big difference. –
Schaaff window.innerWidth
can in fact be larger than the actual (virtual-pixel-based) screen width, if there already is content in the DOM that is larger. In those situations, document.documentElement.clientHeight
still returns the smaller correct viewport width. Which of course is bizarre and completely contrary to what one would expect. –
Grapeshot documentElement.clientHeight
and documentElement.clientWidth
, when called from within an SVG document - always returns 0 for both. In Chrome they return the correct values. –
Hype DOCTYPE
? DOCTYPE
is required for document.documentElement.clientHeight
to be accurate. Otherwise can you give some example numbers? I just checked in Chrome Windows desktop and Chrome iPhone and the .max
technique still worked. Compare to actual("height", "px")
from github.com/ryanve/actual#api –
Gerta Min(clientHeight, innerHeight) || 0
? –
Monegasque Math.min(777, undefined)
is NaN
–
Gerta Min(Min(clientHeight || Infinity, innerHeight || Infinity) || 0)
–
Monegasque innerWidth
seems to sometimes cause style recalculation, whereas clientWidth
doesn't. Seems counter-intuitive, but I thought I'd mention it here anyway. –
Slippery document.documentElement.clientHeight
and ...Width
seeming to be inaccurate, I'm testing on a page that does have a DOCTYPE
, using Chrome Desktop with mobile emulation turned on, and in this scenario those numbers are wrong (significantly larger than they should be). The numbers returned by window.innerHeight
and ...Width
are accurate. Not sure why, and it's more difficult to test on real mobile so I'm not sure about there either.. –
Squash $(window).width()
and $(window).height()
$(window).height();
returns 536, whereas $("html").height();
returns 10599 –
Felicitous You can use the window.innerWidth and window.innerHeight properties.
document.documentElement.clientWidth
is more accurate and more widely supported than window.innerWidth
–
Gerta document.documentElement.clientWidth
gives me the viewport width while window.innerWidth gives me the document width. Yes, that way round. –
Grapeshot If you aren't using jQuery, it gets ugly. Here's a snippet that should work on all new browsers. The behavior is different in Quirks mode and standards mode in IE. This takes care of it.
var elem = (document.compatMode === "CSS1Compat") ?
document.documentElement :
document.body;
var height = elem.clientHeight;
var width = elem.clientWidth;
clientHeight
on the document.documentElement
element, which will give you the viewport size. To get the document size, you would need to do document.body.clientHeight
. As Chetan explains, this behaviour applies to the modern browsers. It is easy to test. Just open a console and type document.documentElement.clientHeight
on several open tabs. –
Sair I looked and found a cross browser way:
function myFunction(){
if(window.innerWidth !== undefined && window.innerHeight !== undefined) {
var w = window.innerWidth;
var h = window.innerHeight;
} else {
var w = document.documentElement.clientWidth;
var h = document.documentElement.clientHeight;
}
var txt = "Page size: width=" + w + ", height=" + h;
document.getElementById("demo").innerHTML = txt;
}
<!DOCTYPE html>
<html>
<body onresize="myFunction()" onload="myFunction()">
<p>
Try to resize the page.
</p>
<p id="demo">
</p>
</body>
</html>
I know this has an acceptable answer, but I ran into a situation where clientWidth
didn't work, as iPhone (at least mine) returned 980, not 320, so I used window.screen.width
. I was working on existing site, being made "responsive" and needed to force larger browsers to use a different meta-viewport.
Hope this helps someone, it may not be perfect, but it works in my testing on iOs and Android.
//sweet hack to set meta viewport for desktop sites squeezing down to mobile that are big and have a fixed width
//first see if they have window.screen.width avail
(function() {
if (window.screen.width)
{
var setViewport = {
//smaller devices
phone: 'width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no',
//bigger ones, be sure to set width to the needed and likely hardcoded width of your site at large breakpoints
other: 'width=1045,user-scalable=yes',
//current browser width
widthDevice: window.screen.width,
//your css breakpoint for mobile, etc. non-mobile first
widthMin: 560,
//add the tag based on above vars and environment
setMeta: function () {
var params = (this.widthDevice <= this.widthMin) ? this.phone : this.other;
var head = document.getElementsByTagName("head")[0];
var viewport = document.createElement('meta');
viewport.setAttribute('name','viewport');
viewport.setAttribute('content',params);
head.appendChild(viewport);
}
}
//call it
setViewport.setMeta();
}
}).call(this);
I was able to find a definitive answer in JavaScript: The Definitive Guide, 6th Edition by O'Reilly, p. 391:
This solution works even in Quirks mode, while ryanve and ScottEvernden's current solution do not.
function getViewportSize(w) {
// Use the specified window or the current window if no argument
w = w || window;
// This works for all browsers except IE8 and before
if (w.innerWidth != null) return { w: w.innerWidth, h: w.innerHeight };
// For IE (or any browser) in Standards mode
var d = w.document;
if (document.compatMode == "CSS1Compat")
return { w: d.documentElement.clientWidth,
h: d.documentElement.clientHeight };
// For browsers in Quirks mode
return { w: d.body.clientWidth, h: d.body.clientHeight };
}
except for the fact that I wonder why the line if (document.compatMode == "CSS1Compat")
is not if (d.compatMode == "CSS1Compat")
, everything looks good.
documentElement.clientWidth
does not respond on device orientation change on iOS. b) displays physical pixels count (practically useless) instead of virtual pixels –
Zackaryzacks If you are looking for non-jQuery solution that gives correct values in virtual pixels on mobile, and you think that plain window.innerHeight
or document.documentElement.clientHeight
can solve your problem, please study this link first: https://tripleodeon.com/assets/2011/12/table.html
The developer has done good testing that reveals the problem: you can get unexpected values for Android/iOS, landscape/portrait, normal/high density displays.
My current answer is not silver bullet yet (//todo), but rather a warning to those who are going to quickly copy-paste any given solution from this thread into production code.
I was looking for page width in virtual pixels on mobile, and I've found the only working code is (unexpectedly!) window.outerWidth
. I will later examine this table for correct solution giving height excluding navigation bar, when I have time.
This code is from http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/
function viewport() {
var e = window, a = 'inner';
if (!('innerWidth' in window )) {
a = 'client';
e = document.documentElement || document.body;
}
return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
}
NB : to read the width, use console.log('viewport width'+viewport().width);
There is a difference between window.innerHeight
and document.documentElement.clientHeight
. The first includes the height of the horizontal scrollbar.
You can do it In Native away, without Jquery or extras
console.log('height default :'+window.visualViewport.height)
console.log('width default :'+window.visualViewport.width)
window.addEventListener('resize',(e)=>{
console.log( `width: ${e.target.visualViewport.width}px`);
console.log( `height: ${e.target.visualViewport.height}px`);
});
It should be
let vw = document.documentElement.clientWidth;
let vh = document.documentElement.clientHeight;
understand viewport: https://developer.mozilla.org/en-US/docs/Web/CSS/Viewport_concepts
shorthand for link above: viewport.moz.one
I've built a site for testing on devices: https://vp.moz.one
A solution that would conform to W3C standards would be to create a transparent div (for example dynamically with JavaScript), set its width and height to 100vw/100vh (Viewport units) and then get its offsetWidth and offsetHeight. After that, the element can be removed again. This will not work in older browsers because the viewport units are relatively new, but if you don't care about them but about (soon-to-be) standards instead, you could definitely go this way:
var objNode = document.createElement("div");
objNode.style.width = "100vw";
objNode.style.height = "100vh";
document.body.appendChild(objNode);
var intViewportWidth = objNode.offsetWidth;
var intViewportHeight = objNode.offsetHeight;
document.body.removeChild(objNode);
Of course, you could also set objNode.style.position = "fixed" and then use 100% as width/height - this should have the same effect and improve compatibility to some extent. Also, setting position to fixed might be a good idea in general, because otherwise the div will be invisible but consume some space, which will lead to scrollbars appearing etc.
This is the way I do it, I tried it in IE 8 -> 10, FF 35, Chrome 40, it will work very smooth in all modern browsers (as window.innerWidth is defined) and in IE 8 (with no window.innerWidth) it works smooth as well, any issue (like flashing because of overflow: "hidden"), please report it. I'm not really interested on the viewport height as I made this function just to workaround some responsive tools, but it might be implemented. Hope it helps, I appreciate comments and suggestions.
function viewportWidth () {
if (window.innerWidth) return window.innerWidth;
var
doc = document,
html = doc && doc.documentElement,
body = doc && (doc.body || doc.getElementsByTagName("body")[0]),
getWidth = function (elm) {
if (!elm) return 0;
var setOverflow = function (style, value) {
var oldValue = style.overflow;
style.overflow = value;
return oldValue || "";
}, style = elm.style, oldValue = setOverflow(style, "hidden"), width = elm.clientWidth || 0;
setOverflow(style, oldValue);
return width;
};
return Math.max(
getWidth(html),
getWidth(body)
);
}
If you are using React, then with latest version of react hooks, you could use this.
// Usage
function App() {
const size = useWindowSize();
return (
<div>
{size.width}px / {size.height}px
</div>
);
}
you can use
window.addEventListener('resize' , yourfunction);
it will runs yourfunction when the window resizes.
when you use window.innerWidth
or document.documentElement.clientWidth
it is read only.
you can use if statement in yourfunction and make it better.
You can simply use the JavaScript window.matchMedia() method to detect a mobile device based on the CSS media query. This is the best and most reliable way to detect mobile devices.
The following example will show you how this method actually works:
<script>
$(document).ready(function(){
if(window.matchMedia("(max-width: 767px)").matches){
// The viewport is less than 768 pixels wide
alert("This is a mobile device.");
} else{
// The viewport is at least 768 pixels wide
alert("This is a tablet or desktop.");
}
});
</script>
© 2022 - 2024 — McMap. All rights reserved.
getComputedStyle
of the expandedhtml
tag. – Zackaryzacks