-
Notifications
You must be signed in to change notification settings - Fork 20.6k
CSS: Make .css("width") & .css("height") return fractional values #2439
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
// Support: Safari 8+ | ||
// Table columns in Safari have non-zero offsetWidth & zero | ||
// getBoundingClientRect().width unless display is changed. | ||
// Support: IE <= 11 only |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've checked this is fixed in Edge.
Not anymore. Mathias just re-enabled it. |
It's still down for me. |
LGTM, assuming you can also cherry-pick to compat and make necessary changes. |
So Chrome and FF try this on Now, i gather, if ppl need subpixels they use So this is:
But we want to do it anyway? |
Site devs cannot choose to not update browsers of their users or defer the update. With libraries it's possible. Also, as @bzbarsky said in #1724, |
Since jsPerf is down, I've set up a simple page locally using Benchmark.js to test it (micro-benchmarks are not great but it's hard to measure otherwise): <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>A page for perf tests</title>
<style>
#test-div-container {
width: 66.6px;
height: 23.4px;
}
#test-div {
width: 33%;
height: 50%;
}
</style>
</head>
<body>
<div id="test-div-container">
<div id="test-div"></div>
</div>
<script src="http://code.jquery.com/jquery-git.js"></script>
<script>
var $j = jQuery.noConflict();
</script>
<script src="jquery.js"></script>
<script src="benchmark.js"></script>
<script>
var suite = new Benchmark.Suite;
var testDiv1 = $j('#test-div');
var testDiv2 = $('#test-div');
// add tests
suite
.add('width without fractions', function() {
testDiv1.css('width');
})
.add('width with fractions', function() {
testDiv2.css('width');
})
.add('height without fractions', function() {
testDiv1.css('height');
})
.add('height with fractions', function() {
testDiv2.css('height');
})
// add listeners
.on('cycle', function(event) {
console.log(String(event.target));
})
.on('complete', function() {
window.s = this;
console.log('Fastest is ' + this.filter('fastest').pluck('name'));
})
// run async
.run({'async': true});
</script>
</body>
</html> Chrome 43:
Firefox 39:
IE11:
Edge (build 10162):
Safari 8:
Overall, the perf penalty is at about 6-9% for IE/Edge/Safari & ~16% for Chrome/Firefox. |
You didn't answer, why we want to do this? Because
So it will now work in Chrome but not in IE9? This will work in mobile Safari but not in Android browser? This is debug nightmare.
With this trajectory, it is easier not to update jQuery at all or use Zepto instead.
What? Do as they did? Deprecate our methods? There is a lot of stuff deprecated in DOM API, users still use them. Even you know this because of one offhand comment, you expect people to know this too? |
Number four to my list |
Btw, i see no deprecation notice in http://dev.w3.org/csswg/cssom-view/#dom-htmlelement-offsetwidth or on mdn.io, i don't see "deprecation" word anywhere in #1724, i see only "Just don't use offset*." This no way near to "deprecation" decision. |
I strongly disagree with such a conclusion. The fact that you upgrade the library yourself is a very strong difference to native APIs. Browsers can't fix a lot of native APIs since they'd break existing sites with no possibility of immediately fix all of them. With libraries it's crucial the developer choses the moment of the upgrade; if the upgrade breaks anything the dev might not deploy it immediately but fix the issues first. This is a huge difference.
This is no different than what we currently have. Try http://output.jsbin.com/mugudi/ on Chrome & Android 2.3. Some browsers round down, some up. You're safe only if you use decimal values for everything.
No, we can change them. |
@markelog To be fair, the issue does include a reason for doing this... #1724 (comment). For browsers that do support subpixel layout, our rounded values are unusable. Returning whatever the browser returns, even if inconsistent across browsers, will be consistent within each browser. In other words, for browsers that support subpixel layout, we can return subpixel values. For the ones that don't, we don't. This makes layout consistent across browsers. |
Right, so why do i need break anything? Between choosing not to break and break, why would user chose the latter?
You did get that i was sarcastic, right :-)?
I see justification to not fix any browser bug ever, "if they don't we don't". This is a big edge-case of small amount of users we are trying to fix here but this fix might be catastrophic to everyone else. |
Migrate issue: jquery/jquery-migrate#112. |
Just for the good record keeping - we decided to land this and see responses from alpha users |
I think landing this for the alpha makes sense. We don't have a good idea of how much users and plugins depend on these numbers being integers. If this breaks some plugins, the user always has the option to delay an upgrade until the plugin is fixed. If the plugin is abandoned and will never be fixed, they have bigger problems than a jQuery upgrade. |
|
If no one opposes, I'll merge it today. |
Fixes gh-1724
-9 bytes, most likely because the IE11 fullscreen workaround got way smaller.
Safari 8 returns 0 for
gBCR().width
for table columns and non-zero value foroffsetWidth
. Older versions don't exhibit this behavior.As for #1724 (comment), I can reproduce the problem only on jsFiddle so it may require an iframe or even weirder setup, who knows. But browsers not supporting fractional values in gBCR differ in what to return anyway, e.g. Android Browser always rounds down, same with
offsetWidth
. I don't think we're going to get consistent data here.IE 10-11 & Edge return non-decimal heights for children divs in dimensions tests so I had to round it. The value is really close but smaller than 100.
Tests pass on IE 9-11, Firefox, Chrome, Safari 6-8, Android 2.3-5.0 & iOS 6-8. Should I add more tests? Not sure what else can I check.
TODO:
compat
version of the patch (they should be similar but IE8 needs special handling)