Interesting bug in Chrome. If a scrollable div is off screen when the page initially loads, then that scrollable div is not scrollable by way of mouse wheel or touch pad gestures until it is given focus (by double clicking somewhere within its element, or selecting text inside of it).
Update This bug is documented here https://code.google.com/p/chromium/issues/detail?id=417345 It remains unfixed as of May 2015. The thread provides some interesting possible solutions with javascript, but I would like to see if anyone has any alternate suggestions for a fix, possibly not involving JS
The Bug When you click on the button to "Show Side Container", the side container will slide into view, and the main container will slide out of view. If you immediately try to scroll using the mouse wheel or two finger gesture on a laptop track pad, nothing will happen. You can use page up and page down on the keyboard however, these do work. You can of course also use the actual scroll by by clicking on it with a mouse.
In firefox and IE, you can use the mouse wheel to scroll on this element
Example http://codepen.io/msorrentino/full/aOYaOM/
HTML
<div class="wrapper">
<div class="page-container">
<button class="show-side">Show Side Container</button>
</div>
<div class="side-container">
<button class="close-side">Close Side Container</button>
<div class="large-content"></div>
</div>
</div>
CSS
html,
body,
*,
*:after,
*:before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
height: 100%;
}
.wrapper {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
}
.page-container, .side-container {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border: 5px solid;
overflow-y: auto;
overflow-x: hidden;
-webkit-transition: -webkit-transform 0.2s cubic-bezier(0.68, 0, 0, 1);
transition: -webkit-transform 0.2s cubic-bezier(0.68, 0, 0, 1), transform 0.2s cubic-bezier(0.68, 0, 0, 1);
}
.page-container {
-webkit-transform: translate(0,0);
transform: translate(0,0);
}
.page-container-hidden {
-webkit-transform: translate(-100%,0);
transform: translate(-100%,0);
}
.side-container {
-webkit-transform: translate(100%,0);
transform: translate(100%,0);
}
.side-container-visible {
-webkit-transform: translate(0,0);
transform: translate(0,0);
}
.large-content {
height: 2000px;
}
JS
$('.show-side').click(function(){
$('.page-container').addClass('page-container-hidden');
$('.side-container').addClass('side-container-visible');
});
$('.close-side').click(function(){
$('.page-container').removeClass('page-container-hidden');
$('.side-container').removeClass('side-container-visible');
});
It gets more interesting If you make the original "page-container" element have enough content that to force it to have overflow, then the "side-container" element no longer displays the aforementioned bug! http://codepen.io/msorrentino/full/WvzgQZ/
Any thoughts on what is happening here are welcome, and any possible fixes would be very welcome.
Came across this question when I encountered a very similar problem with an off-screen menu that moves on-screen when toggled.
Here's the relevant HTML and CSS, simplified:
<div class="menu">
<!-- long list of menu items here -->
</div>
.menu {
position: fixed;
top: 0;
bottom: 0;
left: 0;
transform: translateX(-100%);
transition: transform ease 125ms;
}
.menu--active {
transform: translateX(0);
}
.menu--active is toggled with a button.
Though you're looking for a non-JS solution, I thought I'd post the cleanest workaround I've found in case people end up here with the same problem.
The workaround is to simply force a focus state on the div after the transition has completed. To do this, you first have to give the div a tabindex so that it can be focused.
<div class="menu" tabindex="-1">
<!-- long list of menu items here -->
</div>
(A value of -1 should keep the div out of the normal tab order.)
Then, using a bit of delayed jQuery, focus on the div. This should be invoked along with whatever logic you use to "activate" your div.
setTimeout( function() {
$('.menu').focus();
},150);
The time here is 150 milliseconds, which is just after the transition should have completed. A value equal to that of the transition duration would probably work too, but I set it longer just to be safe.
A more complete example might be:
$('.menuButton').on('click', function() {
$('.menu').addClass('menu--active');
setTimeout( function() {
$('.menu').focus();
},150);
});
Finally, you probably won't want the focus outline on the focused div, so you might choose to remove it with an outline: none in the style rule for your div. In my project, but not in the original example in the question, this actually broke focus on the div, and it went back to being un-scrollable. So I did this instead:
.menu:focus {
outline-color: transparent;
}
I forked the original example and included this solution here: http://codepen.io/johntobinme/full/MaPMgY
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With