detect window width and compensate for scrollbars - Javascript - javascript

How do I detect the width of a user's window with Javascript and account for their scrollbar? (I need the width of the screen INSIDE of the scrollbar). Here's what I have...it seems to work in multiple browsers...except that it doesn't account for the scrollbars..
function browserWidth() {
var myWidth = 0;
if( typeof( window.innerWidth ) == 'number' ) {
//Non-IE
myWidth = window.innerWidth;
} else if( document.documentElement && document.documentElement.clientWidth ) {
//IE 6+ in 'standards compliant mode'
myWidth = document.documentElement.clientWidth;
} else if( document.body && document.body.clientWidth ) {
//IE 4 compatible
myWidth = document.body.clientWidth;
}
return myWidth;
}
any ideas? i need it to work in all browsers;)

A (markedly nasty) workaround if you're only interested in the width is to create a 1px x 100% div and use its offsetWidth. Works on IE>=7, FF, Chrome, Safari and Opera (I've not tried IE6, as we're working to a you're-lucky-it-works-at-all-so-don't-complain-about-rendering-oddities policy thereabouts these days). I hang the div off document.body with attributes { position: 'absolute', top: '-1px', left: 0, width: '100%', height: '1px' }, creating it the first time it's needed.
Works if you can stomach it.

You will find the big summary of what properties are supported on what browsers on this page on quirksmode.org.
Your best bet is probably to grab an element in the page (using document.body where supported, or document.getElementById or whatever), walk its offsetParent chain to find the topmost element, then examine that element's clientWidth and clientHeight.

Just add that before the window.innerWidth() check:
if (typeof(document.body.clientWidth) == 'number') {
// newest gen browsers
width = document.body.clientWidth;
height = document.body.clientHeight;
}

This is what I did - only half a year into learning JavaScript, so this may be a bad fix. First, I created a transparent square image (10px x 10px), but you could also create a non-transparent image and add this to your JavaScript as
document.getElementById('getDimensions').style.visibility = "hidden";
HTML:
<img id="getDimensions" src="images/aSmallBox.png" alt="A small transparent image
meant to determine the dimensions of the viewport" width="10px" height="10px"/>
JavaScript:
//Inside function called by window.onload event handler (could go in CSS file, but
//better to keep it with other related code in JS file)
document.getElementById('getDimensions').style.position = "fixed";
document.getElementById('getDimensions').style.bottom = "0px";
document.getElementById('getDimensions').style.right = "0px";
//Everything below inside function called by window.onresize event handler
var baseWidthCalculation = document.getElementById('getDimensions').offsetLeft;
var baseHeightCalculation = document.getElementById('getDimensions').offsetTop;
//Account for the dimensions of the square img element (10x10)
var viewportWidth = baseWidthCalculation + 10;
var viewportHeight = baseHeightCalculation + 10;

This is a more efficient version of an idea posted here by Tim Salai ( even though you are just beginning, it was brilliant to place an element in the bottom right corner like that ).
var getDimensions = document.createElement("div");
getDimensions.setAttribute("style",
"visibility:hidden;position:fixed;bottom:0px;right:0px;");
document.getElementsByTagName("body")[0].appendChild(getDimensions);
var viewportWidth = getDimensions.offsetLeft;
var viewportHeight = getDimensions.offsetTop;
And here is a modular version
var PageDimensions = function(){
var Width;
var Height;
function pagedimensionsCtor (){
var getDimensions = document.createElement("div");
getDimensions.setAttribute("style" ,
"visibility:hidden;position:fixed;bottom:0px;right:0px;");
document.getElementsByTagName("body")[0].appendChild(getDimensions);
Width = getDimensions.offsetLeft;
Height = getDimensions.offsetTop;
getDimensions.parentNode.removeChild(getDimensions);
}
pagedimensionsCtor();
function Reset(){
pagedimensionsCtor();
}
function GetPageHeight(){
return Height;
}
function GetPageWidth(){
return Width;
}
return{
Reset: Reset,
GetPageHeight: GetPageHeight,
GetPageWidth: GetPageWidth
};
}
Use the modular version:
var page = new PageDimensions();
console.log("viewportWidth: " + page.GetPageWidth() + " viewportHeight: " + page.GetPageHeight());
Bonus feature:
page.Reset();//just in case you think your dimensions have changed

I would compare the "innerWidth" to the width of the body. If the body width > innerwidth, then scrollbars are present.
if (browserWidth() < document.body.offsetWidth) {
doSomething();
}

Another solution you can try is changing some CSS so scrolling happens within your page, instead of the browser window doing it. In the style for body, add overflow:auto. Now the body element includes the scrollbar, so when you get the window width you're measuring the width outside the scrolling container instead of inside it.
This does feel like a potential source of quirkiness, and possibly an accessibility issue, so if you're going for widespread use you might want to test it quite carefully.

Related

How should I write the width of the body of my document as a condition in JavaScript? [duplicate]

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:
Cross-browser #media (width) and #media (height) values 
const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)
const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0)
window.innerWidth and window.innerHeight
gets CSS viewport #media (width) and #media (height) which include scrollbars
initial-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 values
zoom may cause values to be 1px off due to native rounding
undefined in IE8-
document.documentElement.clientWidth and .clientHeight
equals CSS viewport width minus scrollbar width
matches #media (width) and #media (height) when there is no scrollbar
same as jQuery(window).width() which jQuery calls the browser viewport
available cross-browser
inaccurate if doctype is missing
Resources
Live outputs for various dimensions
verge uses cross-browser viewport techniques
actual uses matchMedia to obtain precise dimensions in any unit
jQuery dimension functions
$(window).width() and $(window).height()
You can use the window.innerWidth and window.innerHeight properties.
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;
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.
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.
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.
For detect the Size dynamically
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`);
});
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>
);
}
https://usehooks.com/useWindowSize/
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
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>

How to access screen size within javascript file [duplicate]

How can I get windowWidth, windowHeight, pageWidth, pageHeight, screenWidth, screenHeight, pageX, pageY, screenX, screenY which will work in all major browsers?
You can get the size of the window or document with jQuery:
// Size of browser viewport.
$(window).height();
$(window).width();
// Size of HTML document (same as pageHeight/pageWidth in screenshot).
$(document).height();
$(document).width();
For screen size you can use the screen object:
window.screen.height;
window.screen.width;
This has everything you need to know: Get viewport/window size
but in short:
var win = window,
doc = document,
docElem = doc.documentElement,
body = doc.getElementsByTagName('body')[0],
x = win.innerWidth || docElem.clientWidth || body.clientWidth,
y = win.innerHeight|| docElem.clientHeight|| body.clientHeight;
alert(x + ' × ' + y);
Fiddle
Please stop editing this answer. It's been edited 22 times now by different people to match their code format preference. It's also been pointed out that this isn't required if you only want to target modern browsers - if so you only need the following:
const width = window.innerWidth || document.documentElement.clientWidth ||
document.body.clientWidth;
const height = window.innerHeight|| document.documentElement.clientHeight||
document.body.clientHeight;
console.log(width, height);
Here is a cross browser solution with pure JavaScript (Source):
var width = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
var height = window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight;
A non-jQuery way to get the available screen dimension. window.screen.width/height has already been put up, but for responsive webdesign and completeness sake I think its worth to mention those attributes:
alert(window.screen.availWidth);
alert(window.screen.availHeight);
http://www.quirksmode.org/dom/w3c_cssom.html#t10 :
availWidth and availHeight - The available width and height on the
screen (excluding OS taskbars and such).
But when we talk about responsive screens and if we want to handle it using jQuery for some reason,
window.innerWidth, window.innerHeight
gives the correct measurement. Even it removes the scroll-bar's extra space and we don't need to worry about adjusting that space :)
Full 2020
I am surprised that question have about 10 years and it looks like so far nobody has given a full answer (with 10 values) yet. So I carefully analyse OP question (especially picture) and have some remarks
center of coordinate system (0,0) is in the viewport (browser window without bars and main borders) top left corner and axes are directed to right and down (what was marked on OP picture) so the values of pageX, pageY, screenX, screenY must be negative (or zero if page is small or not scrolled)
for screenHeight/Width OP wants to count screen height/width including system menu bar (eg. in MacOs) - this is why we NOT use .availWidth/Height (which not count it)
for windowWidth/Height OP don't want to count size of scroll bars so we use .clientWidth/Height
the screenY - in below solution we add to position of top left browser corner (window.screenY) the height of its menu/tabls/url bar). But it is difficult to calculate that value if download-bottom bar appears in browser and/or if developer console is open on page bottom - in that case this value will be increased of size of that bar/console height in below solution. Probably it is impossible to read value of bar/console height to make correction (without some trick like asking user to close that bar/console before measurements...)
pageWidth - in case when pageWidth is smaller than windowWidth we need to manually calculate size of <body> children elements to get this value (we do example calculation in contentWidth in below solution - but in general this can be difficult for that case)
for simplicity I assume that <body> margin=0 - if not then you should consider this values when calculate pageWidth/Height and pageX/Y
function sizes() {
const contentWidth = [...document.body.children].reduce(
(a, el) => Math.max(a, el.getBoundingClientRect().right), 0)
- document.body.getBoundingClientRect().x;
return {
windowWidth: document.documentElement.clientWidth,
windowHeight: document.documentElement.clientHeight,
pageWidth: Math.min(document.body.scrollWidth, contentWidth),
pageHeight: document.body.scrollHeight,
screenWidth: window.screen.width,
screenHeight: window.screen.height,
pageX: document.body.getBoundingClientRect().x,
pageY: document.body.getBoundingClientRect().y,
screenX: -window.screenX,
screenY: -window.screenY - (window.outerHeight-window.innerHeight),
}
}
// TEST
function show() {
console.log(sizes());
}
body { margin: 0 }
.box { width: 3000px; height: 4000px; background: red; }
<div class="box">
CAUTION: stackoverflow snippet gives wrong values for screenX-Y,
but if you copy this code to your page directly the values will be right<br>
<button onclick="show()" style="">CALC</button>
</div>
I test it on Chrome 83.0, Safari 13.1, Firefox 77.0 and Edge 83.0 on MacOs High Sierra
Graphical answer:
(............)
function wndsize(){
var w = 0;var h = 0;
//IE
if(!window.innerWidth){
if(!(document.documentElement.clientWidth == 0)){
//strict mode
w = document.documentElement.clientWidth;h = document.documentElement.clientHeight;
} else{
//quirks mode
w = document.body.clientWidth;h = document.body.clientHeight;
}
} else {
//w3c
w = window.innerWidth;h = window.innerHeight;
}
return {width:w,height:h};
}
function wndcent(){
var hWnd = (arguments[0] != null) ? arguments[0] : {width:0,height:0};
var _x = 0;var _y = 0;var offsetX = 0;var offsetY = 0;
//IE
if(!window.pageYOffset){
//strict mode
if(!(document.documentElement.scrollTop == 0)){offsetY = document.documentElement.scrollTop;offsetX = document.documentElement.scrollLeft;}
//quirks mode
else{offsetY = document.body.scrollTop;offsetX = document.body.scrollLeft;}}
//w3c
else{offsetX = window.pageXOffset;offsetY = window.pageYOffset;}_x = ((wndsize().width-hWnd.width)/2)+offsetX;_y = ((wndsize().height-hWnd.height)/2)+offsetY;
return{x:_x,y:_y};
}
var center = wndcent({width:350,height:350});
document.write(center.x+';<br>');
document.write(center.y+';<br>');
document.write('<DIV align="center" id="rich_ad" style="Z-INDEX: 10; left:'+center.x+'px;WIDTH: 350px; POSITION: absolute; TOP: '+center.y+'px; HEIGHT: 350px"><!--К сожалению, у Вас не установлен flash плеер.--></div>');
You can also get the WINDOW width and height, avoiding browser toolbars and other stuff. It is the real usable area in browser's window.
To do this, use:
window.innerWidth and window.innerHeight properties (see doc 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.
To check height and width of your current loaded page of any website using "console" or after clicking "Inspect".
step 1: Click the right button of mouse and click on 'Inspect' and then click 'console'
step 2: Make sure that your browser screen should be not in 'maximize' mode. If the browser screen is in 'maximize' mode, you need to first click the maximize button (present either at right or left top corner) and un-maximize it.
step 3: Now, write the following after the greater than sign ('>') i.e.
> window.innerWidth
output : your present window width in px (say 749)
> window.innerHeight
output : your present window height in px (say 359)
Complete guide related to Screen sizes
JavaScript
For height:
document.body.clientHeight // Inner height of the HTML document body, including padding
// but not the horizontal scrollbar height, border, or margin
screen.height // Device screen height (i.e. all physically visible stuff)
screen.availHeight // Device screen height minus the operating system taskbar (if present)
window.innerHeight // The current document's viewport height, minus taskbars, etc.
window.outerHeight // Height the current window visibly takes up on screen
// (including taskbars, menus, etc.)
Note: When the window is maximized this will equal screen.availHeight
For width:
document.body.clientWidth // Full width of the HTML page as coded, minus the vertical scroll bar
screen.width // Device screen width (i.e. all physically visible stuff)
screen.availWidth // Device screen width, minus the operating system taskbar (if present)
window.innerWidth // The browser viewport width (including vertical scroll bar, includes padding but not border or margin)
window.outerWidth // The outer window width (including vertical scroll bar,
// toolbars, etc., includes padding and border but not margin)
Jquery
For height:
$(document).height() // Full height of the HTML page, including content you have to
// scroll to see
$(window).height() // The current document's viewport height, minus taskbars, etc.
$(window).innerHeight() // The current document's viewport height, minus taskbars, etc.
$(window).outerHeight() // The current document's viewport height, minus taskbars, etc.
For width:
$(document).width() // The browser viewport width, minus the vertical scroll bar
$(window).width() // The browser viewport width (minus the vertical scroll bar)
$(window).innerWidth() // The browser viewport width (minus the vertical scroll bar)
$(window).outerWidth() // The browser viewport width (minus the vertical scroll bar)
Reference: https://help.optimizely.com/Build_Campaigns_and_Experiments/Use_screen_measurements_to_design_for_responsive_breakpoints
With the introduction of globalThis in ES2020 you can use properties like.
For screen size:
globalThis.screen.availWidth
globalThis.screen.availHeight
For Window Size
globalThis.outerWidth
globalThis.outerHeight
For Offset:
globalThis.pageXOffset
globalThis.pageYOffset
...& so on.
alert("Screen Width: "+ globalThis.screen.availWidth +"\nScreen Height: "+ globalThis.screen.availHeight)
If you need a truly bulletproof solution for the document width and height (the pageWidth and pageHeight in the picture), you might want to consider using a plugin of mine, jQuery.documentSize.
It has just one purpose: to always return the correct document size, even in scenarios when jQuery and other methods fail. Despite its name, you don't necessarily have to use jQuery – it is written in vanilla Javascript and works without jQuery, too.
Usage:
var w = $.documentWidth(),
h = $.documentHeight();
for the global document. For other documents, e.g. in an embedded iframe you have access to, pass the document as a parameter:
var w = $.documentWidth( myIframe.contentDocument ),
h = $.documentHeight( myIframe.contentDocument );
Update: now for window dimensions, too
Ever since version 1.1.0, jQuery.documentSize also handles window dimensions.
That is necessary because
$( window ).height() is buggy in iOS, to the point of being useless
$( window ).width() and $( window ).height() are unreliable on mobile because they don't handle the effects of mobile zooming.
jQuery.documentSize provides $.windowWidth() and $.windowHeight(), which solve these issues. For more, please check out the documentation.
I wrote a small javascript bookmarklet you can use to display the size. You can easily add it to your browser and whenever you click it you will see the size in the right corner of your browser window.
Here you find information how to use a bookmarklet
https://en.wikipedia.org/wiki/Bookmarklet
Bookmarklet
javascript:(function(){!function(){var i,n,e;return n=function(){var n,e,t;return t="background-color:azure; padding:1rem; position:fixed; right: 0; z-index:9999; font-size: 1.2rem;",n=i('<div style="'+t+'"></div>'),e=function(){return'<p style="margin:0;">width: '+i(window).width()+" height: "+i(window).height()+"</p>"},n.html(e()),i("body").prepend(n),i(window).resize(function(){n.html(e())})},(i=window.jQuery)?(i=window.jQuery,n()):(e=document.createElement("script"),e.src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js",e.onload=n,document.body.appendChild(e))}()}).call(this);
Original Code
The original code is in coffee:
(->
addWindowSize = ()->
style = 'background-color:azure; padding:1rem; position:fixed; right: 0; z-index:9999; font-size: 1.2rem;'
$windowSize = $('<div style="' + style + '"></div>')
getWindowSize = ->
'<p style="margin:0;">width: ' + $(window).width() + ' height: ' + $(window).height() + '</p>'
$windowSize.html getWindowSize()
$('body').prepend $windowSize
$(window).resize ->
$windowSize.html getWindowSize()
return
if !($ = window.jQuery)
# typeof jQuery=='undefined' works too
script = document.createElement('script')
script.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js'
script.onload = addWindowSize
document.body.appendChild script
else
$ = window.jQuery
addWindowSize()
)()
Basically the code is prepending a small div which updates when you resize your window.
In some cases related with responsive layout $(document).height() can return wrong data that displays view port height only.
For example when some div#wrapper has height:100%, that #wrapper can be stretched by some block inside it. But it's height still will be like viewport height. In such situation you might use
$('#wrapper').get(0).scrollHeight
That represents actual size of wrapper.
I developed a library for knowing the real viewport size for desktops and mobiles browsers, because viewport sizes are inconsistents across devices and cannot rely on all the answers of that post (according to all the research I made about this) : https://github.com/pyrsmk/W
Sometimes you need to see the width/height changes while resizing the window and inner content.
For that I've written a little script that adds a log box that dynamicly monitors all the resizing and almost immediatly updates.
It adds a valid HTML with fixed position and high z-index, but is small enough, so you can:
use it on an actual site
use it for testing mobile/responsive
views
Tested on: Chrome 40, IE11, but it is highly possible to work on other/older browsers too ... :)
function gebID(id){ return document.getElementById(id); }
function gebTN(tagName, parentEl){
if( typeof parentEl == "undefined" ) var parentEl = document;
return parentEl.getElementsByTagName(tagName);
}
function setStyleToTags(parentEl, tagName, styleString){
var tags = gebTN(tagName, parentEl);
for( var i = 0; i<tags.length; i++ ) tags[i].setAttribute('style', styleString);
}
function testSizes(){
gebID( 'screen.Width' ).innerHTML = screen.width;
gebID( 'screen.Height' ).innerHTML = screen.height;
gebID( 'window.Width' ).innerHTML = window.innerWidth;
gebID( 'window.Height' ).innerHTML = window.innerHeight;
gebID( 'documentElement.Width' ).innerHTML = document.documentElement.clientWidth;
gebID( 'documentElement.Height' ).innerHTML = document.documentElement.clientHeight;
gebID( 'body.Width' ).innerHTML = gebTN("body")[0].clientWidth;
gebID( 'body.Height' ).innerHTML = gebTN("body")[0].clientHeight;
}
var table = document.createElement('table');
table.innerHTML =
"<tr><th>SOURCE</th><th>WIDTH</th><th>x</th><th>HEIGHT</th></tr>"
+"<tr><td>screen</td><td id='screen.Width' /><td>x</td><td id='screen.Height' /></tr>"
+"<tr><td>window</td><td id='window.Width' /><td>x</td><td id='window.Height' /></tr>"
+"<tr><td>document<br>.documentElement</td><td id='documentElement.Width' /><td>x</td><td id='documentElement.Height' /></tr>"
+"<tr><td>document.body</td><td id='body.Width' /><td>x</td><td id='body.Height' /></tr>"
;
gebTN("body")[0].appendChild( table );
table.setAttribute(
'style',
"border: 2px solid black !important; position: fixed !important;"
+"left: 50% !important; top: 0px !important; padding:10px !important;"
+"width: 150px !important; font-size:18px; !important"
+"white-space: pre !important; font-family: monospace !important;"
+"z-index: 9999 !important;background: white !important;"
);
setStyleToTags(table, "td", "color: black !important; border: none !important; padding: 5px !important; text-align:center !important;");
setStyleToTags(table, "th", "color: black !important; border: none !important; padding: 5px !important; text-align:center !important;");
table.style.setProperty( 'margin-left', '-'+( table.clientWidth / 2 )+'px' );
setInterval( testSizes, 200 );
EDIT: Now styles are applied only to logger table element - not to all tables - also this is a jQuery-free solution :)
You can use the Screen object to get this.
The following is an example of what it would return:
Screen {
availWidth: 1920,
availHeight: 1040,
width: 1920,
height: 1080,
colorDepth: 24,
pixelDepth: 24,
top: 414,
left: 1920,
availTop: 414,
availLeft: 1920
}
To get your screenWidth variable, just use screen.width, same with screenHeight, you would just use screen.height.
To get your window width and height, it would be screen.availWidth or screen.availHeight respectively.
For the pageX and pageY variables, use window.screenX or Y. Note that this is from the VERY LEFT/TOP OF YOUR LEFT/TOP-est SCREEN. So if you have two screens of width 1920 then a window 500px from the left of the right screen would have an X value of 2420 (1920+500). screen.width/height, however, display the CURRENT screen's width or height.
To get the width and height of your page, use jQuery's $(window).height() or $(window).width().
Again using jQuery, use $("html").offset().top and $("html").offset().left for your pageX and pageY values.
here is my solution!
// innerWidth
const screen_viewport_inner = () => {
let w = window,
i = `inner`;
if (!(`innerWidth` in window)) {
i = `client`;
w = document.documentElement || document.body;
}
return {
width: w[`${i}Width`],
height: w[`${i}Height`]
}
};
// outerWidth
const screen_viewport_outer = () => {
let w = window,
o = `outer`;
if (!(`outerWidth` in window)) {
o = `client`;
w = document.documentElement || document.body;
}
return {
width: w[`${o}Width`],
height: w[`${o}Height`]
}
};
// style
const console_color = `
color: rgba(0,255,0,0.7);
font-size: 1.5rem;
border: 1px solid red;
`;
// testing
const test = () => {
let i_obj = screen_viewport_inner();
console.log(`%c screen_viewport_inner = \n`, console_color, JSON.stringify(i_obj, null, 4));
let o_obj = screen_viewport_outer();
console.log(`%c screen_viewport_outer = \n`, console_color, JSON.stringify(o_obj, null, 4));
};
// IIFE
(() => {
test();
})();
This how I managed to get the screen width in React JS Project:
If width is equal to 1680 then return 570 else return 200
var screenWidth = window.screen.availWidth;
<Label style={{ width: screenWidth == "1680" ? 570 : 200, color: "transparent" }}>a </Label>
Screen.availWidth

Set body width,same as clients window

What i'm looking for,is a way to set the width of the body same as the clients window's,using JAVA.
This code i've borrowed from W3S,but its not working in my case -
function body_width(w)
{
var w = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
var x = document.body;
x.style.width = w;
}
window.onload = body_width(w);
Also i've gave "style="width:;" " to the body
Have you tried using screen.availWidth and screen.availHeight?
The screen.availHeight property returns the height of the visitor's screen, in pixels, minus interface features like the Windows Taskbar.
The screen.availWidth property returns the width of the visitor's screen, in pixels, minus interface features like the Windows Taskbar.
It could be done easily with Viewport-Percentage Lengths:
The viewport-percentage lengths are relative to the size of the initial containing block. When the height or width of the initial containing block is changed, they are scaled accordingly.
HTML
<div>Your Container</div>
And CSS
div {
height:100vh;
}
That is all you need.
Here is JSFiddle example.
Try to set width in % :
<style>
Body{
width:100%;
}
</style>
not window.onload = body_width(w);
its window.onload = body_width;
This option worked out perfectly.
<script>
function body_width(w)
{
var w = screen.availWidth
var x = document.body;
x.style.width = screen.availWidth + "px";
}
window.onload = body_width;
</script>
Thanks 2 ivarz_LV
When I tested, using
body {
height: 100%;
}
won't work. Try using this in style:
body {
height: 100vh;
}
I figured using vh would work better.

scaling divs and images css/javascript depending on the screen

I have div which has inside few divs, few images and two selects. I want to make my main division and all of its content to automatically resize depending on the screen. How can I do it?
Thank you :)
You use media queries for this. It is called responsive design
#media screen and (max-width: 699px) {
div {
width: 40px;
}
}
This will essentially change the width of div to 40px only if the screen width is less than 699px
Further reference:
CSS-Tricks
Here is a tried-and-tested script which even accomodates prehistoric browsers such as IE4. It takes the viewport approach, which means divisions can be updated when a user resizes their browser window.
<script>
window.onResize = function() {
if (window.innerWidth) { // All browsers but IE
myViewportWidth = window.innerWidth;
myViewportHeight = window.innerHeight;
}
else if (document.documentElement && document.documentElement.clientWidth) {
// These functions are for IE6 when there is a DOCTYPE
myViewportWidth = document.documentElement.clientWidth;
myViewportHeight = document.documentElement.clientHeight;
}
else if (document.body.clientWidth) {
// These are for IE4, IE5, and IE6 without a DOCTYPE
myViewportWidth = document.body.clientWidth;
myViewportHeight = document.body.clientHeight;
}
// now call customResize with your chosen new dimensions
// you'll probably need to insert a bit of arithmetic here:
// *calculate new values here*
customResize( MY_NEW_X_VALUE, MY_NEW_Y_VALUE );
}// function
</script>
Once you have the viewport dimensions you can resize your main division according to the specific dimensions of the viewport.
I generally use one main division for the content placed inside the 'body' element for convenience. Then modify the following script according to the dimensions you need.
<script>
function customResize(newWidth, newHeight){
var X = newWidth;
var Y = newHeight;
var e = document.getElementById('mainDiv').style.width = 'X';
var f = document.getElementById('mainDiv').style.height = 'Y';
</script>
Take care to test the code with different browsers however - sometimes odd versions of browsers can return unusual values.

Catch browser's "zoom" event in JavaScript

Is it possible to detect, using JavaScript, when the user changes the zoom in a page?
I simply want to catch a "zoom" event and respond to it (similar to window.onresize event).
Thanks.
There's no way to actively detect if there's a zoom. I found a good entry here on how you can attempt to implement it.
I’ve found two ways of detecting the
zoom level. One way to detect zoom
level changes relies on the fact that
percentage values are not zoomed. A
percentage value is relative to the
viewport width, and thus unaffected by
page zoom. If you insert two elements,
one with a position in percentages,
and one with the same position in
pixels, they’ll move apart when the
page is zoomed. Find the ratio between
the positions of both elements and
you’ve got the zoom level. See test
case.
http://web.archive.org/web/20080723161031/http://novemberborn.net/javascript/page-zoom-ff3
You could also do it using the tools of the above post. The problem is you're more or less making educated guesses on whether or not the page has zoomed. This will work better in some browsers than other.
There's no way to tell if the page is zoomed if they load your page while zoomed.
Lets define px_ratio as below:
px ratio = ratio of physical pixel to css px.
if any one zoom The Page, the viewport pxes (px is different from pixel ) reduces and should be fit to The screen so the ratio (physical pixel / CSS_px ) must get bigger.
but in window Resizing, screen size reduces as well as pxes. so the ratio will maintain.
zooming: trigger windows.resize event --> and change px_ratio
but
resizing: trigger windows.resize event --> doesn’t change px_ratio
//for zoom detection
px_ratio = window.devicePixelRatio || window.screen.availWidth / document.documentElement.clientWidth;
$(window).resize(function(){isZooming();});
function isZooming(){
var newPx_ratio = window.devicePixelRatio || window.screen.availWidth / document.documentElement.clientWidth;
if(newPx_ratio != px_ratio){
px_ratio = newPx_ratio;
console.log("zooming");
return true;
}else{
console.log("just resizing");
return false;
}
}
The key point is difference between CSS PX and Physical Pixel.
https://gist.github.com/abilogos/66aba96bb0fb27ab3ed4a13245817d1e
Good news everyone some people! Newer browsers will trigger a window resize event when the zoom is changed.
I'm using this piece of JavaScript to react to Zoom "events".
It polls the window width.
(As somewhat suggested on this page (which Ian Elliott linked to): http://novemberborn.net/javascript/page-zoom-ff3 [archive])
Tested with Chrome, Firefox 3.6 and Opera, not IE.
Regards, Magnus
var zoomListeners = [];
(function(){
// Poll the pixel width of the window; invoke zoom listeners
// if the width has been changed.
var lastWidth = 0;
function pollZoomFireEvent() {
var widthNow = jQuery(window).width();
if (lastWidth == widthNow) return;
lastWidth = widthNow;
// Length changed, user must have zoomed, invoke listeners.
for (i = zoomListeners.length - 1; i >= 0; --i) {
zoomListeners[i]();
}
}
setInterval(pollZoomFireEvent, 100);
})();
This works for me:
var deviceXDPI = screen.deviceXDPI;
setInterval(function(){
if(screen.deviceXDPI != deviceXDPI){
deviceXDPI = screen.deviceXDPI;
... there was a resize ...
}
}, 500);
It's only needed on IE8. All the other browsers naturally generate a resize event.
There is a nifty plugin built from yonran that can do the detection. Here is his previously answered question on StackOverflow. It works for most of the browsers. Application is as simple as this:
window.onresize = function onresize() {
var r = DetectZoom.ratios();
zoomLevel.innerHTML =
"Zoom level: " + r.zoom +
(r.zoom !== r.devicePxPerCssPx
? "; device to CSS pixel ratio: " + r.devicePxPerCssPx
: "");
}
Demo
Although this is a 9 yr old question, the problem persists!
I have been detecting resize while excluding zoom in a project, so I edited my code to make it work to detect both resize and zoom exclusive from one another. It works most of the time, so if most is good enough for your project, then this should be helpful! It detects zooming 100% of the time in what I've tested so far. The only issue is that if the user gets crazy (ie. spastically resizing the window) or the window lags it may fire as a zoom instead of a window resize.
It works by detecting a change in window.outerWidth or window.outerHeight as window resizing while detecting a change in window.innerWidth or window.innerHeight independent from window resizing as a zoom.
//init object to store window properties
var windowSize = {
w: window.outerWidth,
h: window.outerHeight,
iw: window.innerWidth,
ih: window.innerHeight
};
window.addEventListener("resize", function() {
//if window resizes
if (window.outerWidth !== windowSize.w || window.outerHeight !== windowSize.h) {
windowSize.w = window.outerWidth; // update object with current window properties
windowSize.h = window.outerHeight;
windowSize.iw = window.innerWidth;
windowSize.ih = window.innerHeight;
console.log("you're resizing"); //output
}
//if the window doesn't resize but the content inside does by + or - 5%
else if (window.innerWidth + window.innerWidth * .05 < windowSize.iw ||
window.innerWidth - window.innerWidth * .05 > windowSize.iw) {
console.log("you're zooming")
windowSize.iw = window.innerWidth;
}
}, false);
Note: My solution is like KajMagnus's, but this has worked better for me.
⬤ The resize event works on modern browsers by attaching the event on window, and then reading values of thebody, or other element with for example (.getBoundingClientRect()).
In some earlier browsers it was possible to register resize event
handlers on any HTML element. It is still possible to set onresize
attributes or use addEventListener() to set a handler on any element.
However, resize events are only fired on the window object (i.e.
returned by document.defaultView). Only handlers registered on the
window object will receive resize events.
⚠️ Do resize your tab, or zoom, to trigger this snippet:
window.addEventListener("resize", getSizes, false)
function getSizes(){
let body = document.body
body.width = window.innerWidth
body.height = window.innerHeight
console.log(body.width +"px x "+ body.height + "px")
}
getSizes()
⬤ An other modern alternative: the ResizeObserver API
Depending your layout, you can watch for resizing on a particular element.
This works well on «responsive» layouts, because the container box get resized when zooming.
function watchBoxchange(e){
info.textContent = e[0].contentBoxSize[0].inlineSize+" x "+e[0].contentBoxSize[0].blockSize + "px"
}
new ResizeObserver(watchBoxchange).observe(fluid)
#fluid {
width: 200px;
height:100px;
overflow: auto;
resize: both;
border: 3px black solid;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 8vh
}
<div id="fluid">
<info id="info"></info>
</div>
💡 Be careful to not overload javascript tasks from user gestures events. Use requestAnimationFrame whenever you needs redraws.
I'd like to suggest an improvement to previous solution with tracking changes to window width. Instead of keeping your own array of event listeners you can use existing javascript event system and trigger your own event upon width change, and bind event handlers to it.
$(window).bind('myZoomEvent', function() { ... });
function pollZoomFireEvent()
{
if ( ... width changed ... ) {
$(window).trigger('myZoomEvent');
}
}
Throttle/debounce can help with reducing the rate of calls of your handler.
According to MDN, "matchMedia" is the proper way to do this https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#Monitoring_screen_resolution_or_zoom_level_changes
it's a bit finicky because each instance can only watch one MQ at a time, so if you're interested in any zoom level change you need to make a bunch of matchers.. but since the browser is in charge to emitting the events it's probably still more performant than polling, and you could throttle or debounce the callback or pin it to an animation frame or something - here's an implementation that seems pretty snappy, feel free to swap in _throttle or whatever if you're already depending on that.
Run the code snippet and zoom in and out in your browser, note the updated value in the markup - I only tested this in Firefox! lemme know if you see any issues.
const el = document.querySelector('#dppx')
if ('matchMedia' in window) {
function observeZoom(cb, opts) {
opts = {
// first pass for defaults - range and granularity to capture all the zoom levels in desktop firefox
ceiling: 3,
floor: 0.3,
granularity: 0.05,
...opts
}
const precision = `${opts.granularity}`.split('.')[1].length
let val = opts.floor
const vals = []
while (val <= opts.ceiling) {
vals.push(val)
val = parseFloat((val + opts.granularity).toFixed(precision))
}
// construct a number of mediamatchers and assign CB to all of them
const mqls = vals.map(v => matchMedia(`(min-resolution: ${v}dppx)`))
// poor person's throttle
const throttle = 3
let last = performance.now()
mqls.forEach(mql => mql.addListener(function() {
console.debug(this, arguments)
const now = performance.now()
if (now - last > throttle) {
cb()
last = now
}
}))
}
observeZoom(function() {
el.innerText = window.devicePixelRatio
})
} else {
el.innerText = 'unable to observe zoom level changes, matchMedia is not supported'
}
<div id='dppx'>--</div>
You can also get the text resize events, and the zoom factor by injecting a div containing at least a non-breakable space (possibly, hidden), and regularly checking its height. If the height changes, the text size has changed, (and you know how much - this also fires, incidentally, if the window gets zoomed in full-page mode, and you still will get the correct zoom factor, with the same height / height ratio).
<script>
var zoomv = function() {
if(topRightqs.style.width=='200px){
alert ("zoom");
}
};
zoomv();
</script>
On iOS 10 it is possible to add an event listener to the touchmove event and to detect, if the page is zoomed with the current event.
var prevZoomFactorX;
var prevZoomFactorY;
element.addEventListener("touchmove", (ev) => {
let zoomFactorX = document.documentElement.clientWidth / window.innerWidth;
let zoomFactorY = document.documentElement.clientHeight / window.innerHeight;
let pageHasZoom = !(zoomFactorX === 1 && zoomFactorY === 1);
if(pageHasZoom) {
// page is zoomed
if(zoomFactorX !== prevZoomFactorX || zoomFactorY !== prevZoomFactorY) {
// page is zoomed with this event
}
}
prevZoomFactorX = zoomFactorX;
prevZoomFactorY = zoomFactorY;
});
Here is a clean solution:
// polyfill window.devicePixelRatio for IE
if(!window.devicePixelRatio){
Object.defineProperty(window,'devicePixelRatio',{
enumerable: true,
configurable: true,
get:function(){
return screen.deviceXDPI/screen.logicalXDPI;
}
});
}
var oldValue=window.devicePixelRatio;
window.addEventListener('resize',function(e){
var newValue=window.devicePixelRatio;
if(newValue!==oldValue){
// TODO polyfill CustomEvent for IE
var event=new CustomEvent('devicepixelratiochange');
event.oldValue=oldValue;
event.newValue=newValue;
oldValue=newValue;
window.dispatchEvent(event);
}
});
window.addEventListener('devicepixelratiochange',function(e){
console.log('devicePixelRatio changed from '+e.oldValue+' to '+e.newValue);
});
Here is a native way (major frameworks cannot zoom in Chrome, because they dont supports passive event behaviour)
//For Google Chrome
document.addEventListener("mousewheel", event => {
console.log(`wheel`);
if(event.ctrlKey == true)
{
event.preventDefault();
if(event.deltaY > 0) {
console.log('Down');
}else {
console.log('Up');
}
}
}, { passive: false });
// For Mozilla Firefox
document.addEventListener("DOMMouseScroll", event => {
console.log(`wheel`);
if(event.ctrlKey == true)
{
event.preventDefault();
if(event.detail > 0) {
console.log('Down');
}else {
console.log('Up');
}
}
}, { passive: false });
I'am replying to a 3 year old link but I guess here's a more acceptable answer,
Create .css file as,
#media screen and (max-width: 1000px)
{
// things you want to trigger when the screen is zoomed
}
EG:-
#media screen and (max-width: 1000px)
{
.classname
{
font-size:10px;
}
}
The above code makes the size of the font '10px' when the screen is zoomed to approximately 125%. You can check for different zoom level by changing the value of '1000px'.

Categories