So I have this in IE11...
ROUNDED UP (I think...)
console.log($(document).width()); // 808px;
NOT ROUNDED
console.log($("html")[0].getBoundingClientRect().width); // 807.30993px;
ROUNDED DOWN (or to nearest integer)
console.log($("html").width()); //807px;
So apparently, either $(document) and $("html") are the same, and jQuery is rounding the html element down instead of up like the browser. Or IE11 gives the $(document) some extra room, boosting the amount of pixels HIGHER than html?
I thought html was supposed to represent the whole document?
MY QUESTION:
Should they be the same width? Like in Firefox, Chrome, etc.
Here is an answer to a similar question:
In JavaScript, the document keyword is a handle on the object that contains the HTMLDocument.
So they are not the same, document is an object , which also contains html for the page.
Now when you get the width from the html and document.
console.log($("html").width());
gives you the width of the html.
and console.log($(document).width());
gives you the width of visible part of the document, so apperently width of <html> itself, but there is a difference , if you have applied a margin to html, then the width of document is a sum of width of html and the margin applied to it.
See this example http://jsfiddle.net/bbke9n59/
<div style='background:red;height:30px;'></div>
html{
margin:20px;
}
here, in my browser i get,
console.log('html='+$("html").width()); // width 630
console.log('document='+$(document).width());// width 670
Exactly, 40px difference in the width, thats only the margin applied to the html
Now this was all about chrome and firefox,
About IE
IE-9
when I run the same page on IE-9
console.log('html='+$("html").width()); // width 570
console.log('document='+$(document).width());// width 570
No difference in width of html and document( there should have been really)
IE-11
when I run the same page on IE-11
console.log('html='+$("html").width()); // width 517
console.log('document='+$(document).width());// width 557
Exact difference of 40. just as chrome and firefox showed.
So I am no longer able to reproduce the problem of rounding( in any of the browsers), so for me, I guess the problem is not with the rounding up using jquery(if that was the problem then jquery would have rounded up the width for document and html both, and still make them same width)
Related
I found differencies between browsers how they report computed style dimensions when browser window is zoomed. The JSBIN example is in http://jsbin.com/pilohonevo/2/. The code is as follows:
$(window).resize(function()
{
var width1=$(".class1").css("width");
$(".class1").css("width",width1);
var width2="200px";
$(".class2").css("width",width2);
var width3=$(".class3").css("width");
$("#width1").html(width1);
$("#width2").html(width2);
$("#width3").html(width3);
$("#overflow1").html($(".overflow1")[0].scrollWidth);
$("#overflow2").html($(".overflow2")[0].scrollWidth);
$("#overflow3").html($(".overflow3")[0].scrollWidth);
});
When you zoom to minimum by pressing CMD- few times and then back to 100% by pressing CMD+ few times, in Chrome (Mac Version 38.0.2125.111), you get the following values:
The white DIV 1 reports its width as 203px, although DIV 2 and 3 reports 200px. Also scrollWidth is 203, which is wrong as well. This means that you cannot use getComputedStyle or jQuerys .css() to get dimensions if you are not sure that browser window is not zoomed. And because zooming is not cancelable you can never be sure and you can never trust to those dimensions. I tested also $(elem).scrollLeft() and $(elem).scrollTop() and those are unreliable as well when zoomed.
So a workaround can be to use "raw" values, not "computed" values.
Is there a cross-browser javascript or jQuery method to get something like getUnComputedStyle() which determines dimensions using raw values from stylesheets and/or style attribute, because they are the only ones that are zoom-safe?
Determining zoom level and make corrections based on that is unreliable according to my tests, because there are browser differencies and error levels in different style properties are not consistently related to zoom level.
(Firefox Mac 33.1 and Safari Mac version 7.1 (9537.85.10.17.1) and IE 11 Win and emulated modes down to version 7 report correct values.
Opera Mac 25.0.1614.68, Safari Win 5.1.7 and the above reported Chrome report wrong values.)
I've reproduced this with Chrome 49 and JQuery 1.11, not in FF and not in Internet Explorer.
However, I believe this to be an artifact of the code as well. The only divs that show this problem are div1 and overflow1, which both use the same system of setting the width to the computed width, repeatedly. What happens is that for some zooms the computed value is 201. You set the width to 201, so for some zooms the computed value becomes 202 and so on. I got 204, for example.
In the Chrome debugger, at zoom 67%, the reported width appears as 199.981, but the values available to Javascript are integers. scrollWidth is 199 while clientWidth and offsetWidth are 200. All of the jQuery width methods return 200 (width, innerWidth, outerWidth). At zoom 33%, scrollWidth and jQuery widths all return 201, althought the debugger reported width is still 199.981.
My assertion is that the problem is a bug in Chrome and probably related to rounding.
As described here: Getting the actual, floating-point width of an element you can get the actual floating point value reported by the debugger with .getBoundingClientRect(). If you want to be completely safe, try using that one.
If I understand what you are trying to accomplish correctly (and if I don't please say so and I'll try to improve my answer), and assuming you have already managed to catch the zooming event some how (which is not a given), you could:
Clone the div you are trying to get the CSS styles from;
Append the clone to the dom in an unobtrusive way (ie, a way in which it will not cover any other elements on the document);
Remove it's style attribute (just in case it was set by other scripts or functions);
Get all the styles you need from it;
Finally, remove the clone from the dom when you are done.
This demo works for me, regardless of page zoom.
jQuery(function($) {
function getRawStyles(sel, styles) {
sel = $(sel);
var clone = sel.clone().removeAttr("style").attr("class", "cloneDiv").insertBefore(sel);
$.each(styles, function(index, style) {
console.log( style + ": " + $(clone[0]).css(style) );
});
$(".cloneDiv").remove();
}
$(document).ready(function() {
$("button", this).on("click", function() {
getRawStyles("#myDiv", ["height", "width"]);
});
});
});
#myDiv {
background: grey;
height: 50px;
width: 200px;
}
.cloneDiv {
left: -10000;
opacity: 0;
top: -10000;
position: absolute;
z-index: -1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="myDiv" style="height:200px; width: 100px"></div>
<br/>
<button>Log Computed Styles</button>
I have no idea why, but clientWidth and clientHeight are always returning zero when I run this from IE in IE9 compat View, or IE7. It works for everything else.
Very simple code snippet with problem (so that you can try it too):
http://jsfiddle.net/nz2DA/
The code snippet found above is as follows...
I have a page containing the following HTML snippet:
<div id='aaa'>aaaaaa</div>
And my javascript to test the clientWidth and clientHeight functions are as follows:
var el = $('#aaa')[0];
alert('Client width and height: '+ el.clientWidth + ' X ' + el.clientHeight);
This always pops up an alert with "0 X 0" when I run in IE7 or IE9 Compatibility mode.
Any help or explanation would really be appreciated. Thanks!
This is happening because of the "hasLayout" property in IE, and your div on its own does not "have layout". For more information, see http://www.satzansatz.de/cssd/onhavinglayout.html
Luckily you can trigger an element to have layout, which is why adding the "float:left" style works in the answer above. There are other triggers you can use too though that don't change the page. This one gives me proper values for clientWidth and clientHeight:
<div id="aaa" style="zoom: 1">aaaaaa</div>
The article says that setting "min-width: 0" should also work but it didn't for me. Setting "display: inline-block" worked OK but that might change your page. You can set these triggers in CSS so that the HTML doesn't need to change at all.
I tested your code and following are the observations.
in IE(sucks!), if you didn't apply any styles for the "aaa" element IE won't calculate any width and height. So JS simply give you 0. But if you look at the box model from the IE dev tool bar you will see some value. So if you use float:left to that element JS will return a value, which is correct and all browsers will give you the same output.
Since you are using jQuery why don't you use width() or outerWidth() or innerWidth(). These methods are generelaized for the every browsers. Simply if you use width() you will see a very large width since you didn't apply any styles. In IE if element doesn't have an float value it gets it's parent width.In your case it's window width.
So if I modify your code to get correct width and height would be:
HTML:
<div id="aaa" style="float:left;">aaaaaa</div>
JS:
var el = $('#aaa')[0];
alert('Client width and height: '+ el.clientWidth + ' X ' + el.clientHeight);
Please let me know if you need more clarifications...
cheers!
Try offsetHeight property of internet explorer.
So I am trying to use the CSS hack to set the max-height for a div in IE8 like this
height: expression( this.scrollHeight > 333 ? "333px" : "auto" );
I was wondering if anyone knew of a way to change that to a percentage, instead of a fixed pixel size? It would be fantastic if you could. Thanks!
Basically, I just want to say if this.scrollHeight is > window.height * .75 or something.
-Geoff
Not sure exactly what you want to accomplish but it can be done without javascript like this:
http://jsfiddle.net/KFyM4/6/
The trick is this:
max-height:33%;height:auto !important;height:33%;
And it works even in IE6. The only catch is that the parent element has to have a fixed height set so that it knows from what number to calculate the %.
So if you are doing it on browser window you will have to get the height of window and apply it to your body trough javascript - rest can be done trough css.
I've run into an odd issue with what appears to be various versions of Webkit browsers. I'm trying to position an element on the center of the screen and to do the calculations, I need to get various dimensions, specifically the height of the body and the height of the screen. In jQuery I've been using:
var bodyHeight = $('body').height();
var screenHeight = $(window).height();
My page is typically much taller than the actual viewport, so when I 'alert' those variables, bodyHeight should end up being large, while screenHeight should remain constant (height of the browser viewport).
This is true in
- Firefox
- Chrome 15 (whoa! When did Chrome get to version 15?)
- Safari on iOS5
This is NOT working in:
- Safari on iOS4
- Safari 5.0.4
On the latter two, $(window).height(); always returns the same value as $('body').height()
Thinking it was perhaps a jQuery issue, I swapped out the window height for window.outerHeight but that, too, does the same thing, making me think this is actually some sort of webkit problem.
Has anyone ran into this and know of a way around this issue?
To complicate things, I can't seem to replicate this in isolation. For instance: http://jsbin.com/omogap/3 works fine.
I've determined it's not a CSS issue, so perhaps there's other JS wreaking havoc on this particular browser I need to find.
I've been fighting with this for a very long time (because of bug of my plugin) and I've found the way how to get proper height of window in Mobile Safari.
It works correctly no matter what zoom level is without subtracting height of screen with predefined height of status bars (which might change in future). And it works with iOS6 fullscreen mode.
Some tests (on iPhone with screen size 320x480, in landscape mode):
// Returns height of the screen including all toolbars
// Requires detection of orientation. (320px for our test)
window.orientation === 0 ? screen.height : screen.width
// Returns height of the visible area
// It decreases if you zoom in
window.innerHeight
// Returns height of screen minus all toolbars
// The problem is that it always subtracts it with height of the browser bar, no matter if it present or not
// In fullscreen mode it always returns 320px.
// Doesn't change when zoom level is changed.
document.documentElement.clientHeight
Here is how height is detected:
var getIOSWindowHeight = function() {
// Get zoom level of mobile Safari
// Note, that such zoom detection might not work correctly in other browsers
// We use width, instead of height, because there are no vertical toolbars :)
var zoomLevel = document.documentElement.clientWidth / window.innerWidth;
// window.innerHeight returns height of the visible area.
// We multiply it by zoom and get out real height.
return window.innerHeight * zoomLevel;
};
// You can also get height of the toolbars that are currently displayed
var getHeightOfIOSToolbars = function() {
var tH = (window.orientation === 0 ? screen.height : screen.width) - getIOSWindowHeight();
return tH > 1 ? tH : 0;
};
Such technique has only one con: it's not pixel perfect when page is zoomed in (because window.innerHeight always returns rounded value). It also returns incorrect value when you zoom in near top bar.
One year passed since you asked this question, but anyway hope this helps! :)
I had a similar problem. It had to do with 2 thing:
Box-sizing CSS3 property:
In the .height() jQuery documentation I found this:
Note that .height() will always return the content height, regardless of the value of the CSS box-sizing property. As of jQuery 1.8, this may require retrieving the CSS height plus box-sizing property and then subtracting any potential border and padding on each element when the element has box-sizing: border-box. To avoid this penalty, use .css( "height" ) rather than .height().
This may apply to $('body').height().
Document ready vs Window.load
$(document).ready() is run when the DOM is ready for JS but it's possible that images haven't finished loading yet. Using $(window).load() fixed my problem. Read more.
I hope this helps.
It is 2015, we are at iOS 8 now. iOS 9 is already around the corner. And the issue is still with us. Sigh.
I have implemented a cross-browser solution for the window size in jQuery.documentSize. It stays clear of any kind of browser sniffing and has been heavily unit-tested. Here's how it works:
Call $.windowHeight() for the height of the visual viewport. That is the height of the area you actually see in the viewport at the current zoom level, in CSS pixels.
Call $.windowHeight( { viewport: "layout" } ) for the height of the layout viewport. That is the height which the visible area would have at 1:1 zoom - the "original window height".
Just pick the appropriate viewport for your task, and you are done.
Behind the scenes, the calculation roughly follows the procedure outlined in the answer by #DmitrySemenov. I have written about the steps involved elsewhere on SO. Check it out if you are interested, or have a look at the source code.
Try this :
var screenHeight = (typeof window.outerHeight != 'undefined')?Math.max(window.outerHeight, $(window).height()):$(window).height()
A cross browser solution is set that by jQuery
Use this property:
$(window).height()
This return a int value that represents the size of visible screen height of browser in pixels.
Hi I currently have 2 pages (index.html and iframe_contents.html). Both are on the same domain.
I am currently trying to get the iframe to dynamically resize based on the contents size.
I was using this to assist me http://benalman.com/code/projects/jquery-resize/examples/resize/ and it works if the iframe_contents body tag gets larger or smaller on Firefox and IE 7/8/9 but for webkit it only can grow and can never shrink
I've narrowed it down to the body tag in iframe_contents.html not shrinking when content height changes but only in the iframe. When iframe_contents.html is not in a iframe if I shrink / enlarge elements the bodies overall height changes.
Is this a webkit specific issue?
After reading lots of answers here they all had the same issue with not resizing smaller when needed. I think most people are just doing a one-off resizing after the frame loads, so maybe don't care. I need to resize again anytime the window size changes. So for me, if they made the window narrow the iframe would get very tall, then when they make the window larger it should get shorter again. This wasn't happening on some browsers because the scrollHeight, clientHeight, jquery height() and any other height I could find with DOM inspectors (FireBug/Chrome Dev Tools) did not report the body or html height as being shorter after the iframe was made wider. Like the body had min-height 100% set or something.
For me the solution was to make the iframe 0 height, then check the scrollHeight, then set to that value. To avoid the scrollbar on my page jumping around, I set the height of the parent (that contains the iframe) to the iframe height to keep the total page size fixed while doing this.
I wish I had a cleaner sample, but here is the code I have:
$(element).parent().height($(element).height());
$(element).height(0);
$(element).height($(element).contents().height());
$(element).parent().height("");
element is my iframe.
The iframe has width: 100% style set and is inside a div with default styles (block).
Code is jquery, and sets the div height to the iframe height, then sets iframe to 0 height, then sets iframe to the contents height. If I remove the line that sets the iframe to 0 height, the iframe will get larger when needed, but never smaller.
This may not help you much but here is a function we have in what would be your iframe_contents.html page. It will attempt to resize the iframe in which it is loaded in a sort of self-resizing, cross-browserish, pure-JavaScript kind of way:
function makeMeFit() {
if (top.location == document.location) return; // if we're not in an iframe then don't do anything
if (!window.opera && !document.mimeType && document.all && document.getElementById) {
parent.document.getElementById('youriframeid').style.height = (this.document.body.offsetHeight + 30) + "px";
} else if (document.getElementById) {
parent.document.getElementById('youriframeid').style.height = (this.document.body.scrollHeight + 30) + "px"
}
}
You could put calls to it in a resize() event or following an event that changes the height of your page. The feature-testing in that method should separate out WebKit browsers and pick the correct height property.