I have the following simple set-up:
document.getElementById('inner').addEventListener('click', ({ target }) => {
target.classList.add('match');
});
#container {
background: green;
overflow: auto;
width: 200px;
height: 100px;
}
#inner {
width: 210px;
height: 110px;
}
#inner.match {
width: 200px;
height: 100px;
}
<div id="container">
<div id="inner"></div>
</div>
I have the following simple set-up:
document.getElementById('inner').addEventListener('click', ({ target }) => {
target.classList.add('match');
});
#container {
background: green;
overflow: auto;
width: 200px;
height: 100px;
}
#inner {
width: 210px;
height: 110px;
}
#inner.match {
width: 200px;
height: 100px;
}
<div id="container">
<div id="inner"></div>
</div>
Upon clicking the inner element, I'd expect the scrollbars on the parent to disappear since the two elements now have matching sizes. This works as expected in Firefox.
However the container element doesn't lose scrollbars in Chrome as can be seen in the below screenshot:
The scrollbars themselves create an offset large enough to create overflowing.
Is this a webkit-specific issue? Is there a cross-browser, reliable solution to this (seemingly trivial) issue?
I'm looking for a solution that doesn't change the parent's properties as my content (#inner
) will be placed in DOM I don't have control over.
So far I've tried hiding/showing and/or detaching/reinserting the element at different points of execution, but the problem persists, likely because the operations are simply optimized away.
The issue occurs both in Jsfiddle and in the Stack snippet.
The bug has been filed on Webkit Bugzilla.
Share Improve this question edited Feb 12, 2018 at 10:25 Etheryte asked Dec 14, 2014 at 22:35 EtheryteEtheryte 25.3k12 gold badges76 silver badges120 bronze badges 12- what about setting the parent element to overflow: hidden on click? I'm on the same version of Chrome on OS X and am unable to reproduce the issue in your jsfiddle. – Aweary Commented Dec 14, 2014 at 22:37
- @Aweary That's something I'm looking to avoid since my content will be placed in DOM I don't control. While that would probably work as a workaround, it doesn't practically solve nor explain the issue. – Etheryte Commented Dec 14, 2014 at 22:38
- I'm unable to reproduce the issue in Chrome 39.0.2171.95 on OS X 10.10. Do you possibly have any extensions that may be interfering? – Aweary Commented Dec 14, 2014 at 22:40
- 1 I was able to reproduce it on my lab Mac (OS X 10.10) running Chrome (same version) as well as Safari 8. Not sure why my portable isn't having the issue. – Aweary Commented Dec 14, 2014 at 23:19
- 1 Tested in Firefox 34.0.1 on Windows and the problem does not occur. Tested in Opera 26.0.1656.32 on Windows and the problem occurs. Tested in Safari 5.1.7 on Windows and the problem occurs. Judging from all this testing, it looks like it is specific to Webkit. Non-Webkit browsers don't have the problem. – TylerH Commented Dec 14, 2014 at 23:26
4 Answers
Reset to default 5Update: This issue seems to be fixed in the latest version, I haven't kept track which release specifically though.
A workaround that doesn't involve addressing the parent is to force a browser redraw after the styles are applied.
document.getElementById('inner').addEventListener('click', ({ target }) => {
target.classList.add('match');
//Force redraw
target.style.display='none';
target.offsetHeight; //Won't work without this
target.style.display='';
});
#container {
background: green;
overflow: auto;
width: 200px;
height: 100px;
}
#inner {
width: 210px;
height: 110px;
}
#inner.match {
width: 200px;
height: 100px;
}
<div id="container">
<div id="inner"></div>
</div>
I can't guarantee that this is a solution that works consistently (see the linked thread regarding forcing a redraw for possible issues), but at least in this specific case this seems to work through my initial testing.
I've filed a bug with Webkit describing all the above behavior, but until then, this is a viable option.
Below are three solutions that work around this problem in Chrome.
Solution 1
$('.i').on('click', function() {
var t = $(this);
t.css({
width: '100%',
height: '100%'
});
});
Solution 2
$('.i').on('click', function() {
var t = $(this);
t.css({
width : '200px',
height : '100px',
zoom : 0.5
});
setTimeout(function(){
t.css({
zoom : 1
})}, 1);
});
Solution 3
Works using animation
$('.i').on('click', function() {
var t = $(this);
t.css({
width: '100%',
height: '100%',
'-webkit-animation': 'animate 0.01s, linear'
});
});
Add to CSS:
/* Chrome, Safari, Opera */
@-webkit-keyframes animate {
from {width: 180px; height: 100px;}
to {width: 200px; height: 100px;}
}
To remove scrollbar, you need to redraw parent $('.c') element. But simple hide (style="display:none;"), and then show (style="display:block;") has no effect at all. By updating property of overflow, you need to check everytime what width and hight you are updating and as based on conditions, you have to change value of overflow property.
Try Below Code
$('.i').on('click', function() {
var t = $(this);
t.css({
width: 200,
height: 100
})
$('.c').slideUp(0).slideDown(0); // added
});
I tried jquery slideUp() and slideDown() methods with value 0. Its working fine on windows chrome and safari. I hope it will also work on Mac's browser. FYI : It is also working fine with jquery hide() and show() methods with value 0.
From all the browser testing it seems that this issue is reproducible and isolated to webkit-based browsers.
I remend seeing if there is an open ticket with webkit, or filing a bug report: https://bugs.webkit/
This old ticket seems to be related to your issue. Outside of manipulating the parent element (which you stated was not practical), I'm not sure there are any workarounds.