Keep Overflow Content Scrolling Unresponsive Until Clicked Using jQuery
The other day, I was using a website (can't remember which one), when I stumbled upon a UX (User Experience) design pattern that was so obvious, I can't believe I had never thought of it before! The page I was on had some large, embedded content area (like a Terms of Service Agreement) that would have normally been scrollable; however, on this site, the "scrollability" of the embedded content area was not activated until I clicked into it. This blew my mind and, I wanted to see if I could accomplish the same with JavaScript and jQuery.
Run this demo in my JavaScript Demos project on GitHub.
Normally, I dislike those embedded content areas because they act as "mouse traps," preventing the "intended" scrolling behavior from bubbling up to the root document. Most people couldn't care less about the content that is rendered in these large, embedded areas; so, the fact that you can accidentally scroll them is nothing but insult to injury.
With just a little bit of jQuery, however, we can quickly solve this problem. All we have to do is turn the "overflow:auto" into an "overflow:hidden" until the user clicks the scrollable container. Then, we simply toggle the scrollability and let the browser do the rest:
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>
Keep Overflow Content Scrolling Unresponsive Until Clicked Using jQuery
</title>
<style type="text/css">
div.overflowable {
border: 2px solid #FF3399 ;
height: 150px ;
overflow: auto ;
padding: 1px 16px 1px 16px ;
width: 500px ;
}
div.overflowable.unresponsive {
border-color: #CCCCCC ;
cursor: pointer ;
overflow: hidden ;
}
</style>
</head>
<body>
<h1>
Keep Overflow Content Scrolling Unresponsive Until Clicked Using jQuery
</h1>
<p>
Here is a long page; but, on the page, we have another
area of content that can be scrolled independently using
CSS overflow.
</p>
<p>
<strong>Content You Don't Really Care About</strong>:
</p>
<!-- BEGIN: Overflow Content. -->
<div class="overflowable unresponsive">
<p class="repeatMe">
This is the sub-content area - independently scrollable.
</p>
</div>
<!-- END: Overflow Content. -->
<p class="repeatMe">
This is part of the main page content.
</p>
<!-- Load scripts. -->
<script type="text/javascript" src="../../vendor/jquery/jquery-2.0.3.min.js"></script>
<script type="text/javascript">
// When the content area is clicked, remove the "unresponsive"
// class. This will allow the overflow to take on the "auto"
// behavior, instead of the "hidden" behavior.
$( "div.overflowable" ).click(
function( event ) {
$( this ).toggleClass( "unresponsive" );
}
);
// Set up the "filler" content to make the page and the
// sub-content scroll-worthy.
$( "p.repeatMe" ).each(
function() {
var root = $( this );
for ( var i = 0 ; i < 20 ; i++ ) {
root.after( $.clone( this ) );
}
}
);
</script>
</body>
</html>
Obviously, I wouldn't do this for all overflow-auto content. This would be reserved for content that you have to have on the page, but that you don't really care if people read (such as anything related to legal mumbo-jumbo). Anyway, when I came across this design pattern, I thought it was just brilliant.
Want to use code from this post? Check out the license.
Reader Comments
Makes sense to me. But I think it should be a toggle. You click into the area, then it's scrollable. Click out of the area, it becomes un-scrollable again. Rinse, repeat. :)
@Kyle,
It's funny you mention that - now that I think of it, that is how the page worked (the one that I stumbled across). If I recall correctly, the sub-content "deactivated" if you:
1. Clicked outside of it.
2. Scrolled the parent content.
I had completely forgot about that level of interaction. Good eye!
You can get the same affect w/pure CSS too:
http://jsfiddle.net/dswitzer/6Ye7B/embedded/result/
I had to change the <div> to an <a> so that element would actually get focus. Tried to use a <button> element (which would be more correct) but scrolling a button element didn't seem to work right for me, but I didn't spend much time playing with it.
I've been playing with http://datatables.net/ and your blog post gave me an idea. I wrote a quick proof-of-concept that does a SELECT TOP 10 * to display the opening screen very quickly, and then in AJAX, I fill out the "real" table inside a hidden div. When the user clicks anywhere on the page, the fake div is then hidden and the real table of 5000+ rows is revealed. Works pretty neat.
great interaction .. maybe it is also worth doing that on hover .. which will remove the need for a JS code and be on pure CSS .. plus as @kyle mentioned clikcing outside the container should toggle it back to normal .. a quick way maybe of doing that would be:
//handling the hiding of the entity pop when clicking anywhere else in the document
$(document).mouseup(function(e)
{
var container = $(selector);
if (container.has(e.target).length === 0) container.hide();
});
The :focus approach is pretty cool! I hadn't even considered that. I think the only time I ever use the :focus pseudo-selector is when I want to _remove_ something from the UI (like the dotted-outline things get sometimes).
@Admad, good thinking. The only problem with using :hover is that you sort of end up back at the beginning where the scollable area may "take over" the mouse interaction when your intent is to scroll the parent page.
In general, though, using the CSS is definitely groovy! Great thinking!
Hey Dan,
I tried your pure css demo for this. The CSS changed on the mouse click but as soon as the mouse button was up the div reverted back to the unresponsive class.
Just a heads up.
larry
Would the above work if still on jQuery 1.10.2?
thats a great concept.
Really appreciate your hard work.
Keep it up
Thanks for this. I was looking for this everywhere.
However, the jquery didn't work. So, I designed my own version. Felt like I should share.
Use this script.
<script type="text/javascript">
function changeClass(x)
{
if( x.className == "overflowable") {
x.className = "unresponsive";
}
else if ( x.className == "unresponsive") {
x.className = "overflowable";
}
}
----------------------------------------------
In your <div> tag. Do this:
<div class=" unresponsive" onclick="changeClass(this)" >
Hope that helps anyone who couldnt get the jquery to work.
That's all good, except, keyboard users have no way to access your content.