I noticed a subtle but nice feature on the Google News main page recently. The left-hand navigation that has the various section headings remains fixed to the top left area as you scroll down but it does not overlap the top banner area. Also, if your browser window is too small to fit the entire navigation vertically, when you mouseover the navigation area a set of vertical scroll bars appears. After a little digging it turns out they did this with a combination of CSS and JavaScript. Here’s a simple demo I’ve set up that illustrates how I believe they achieved the effect.
Initially, the sidebar area is set to a non-fixed position. In my example I’m just floating it to the left of the main content area. It also has overflow set to hidden. Here is the CSS for the sidebar:
<style type="text/css"> #sidebar { float: left; width: 180px; margin: 10px 0 0 0; font-size: 11px; line-height: 15px; } #sidebar #pinned { width: 180px; height: 100%; overflow-y: hidden; } #sidebar #pinned.pin-set { position: fixed; height: 100%; top: 0px; z-index: 99; } #sidebar:hover #pinned { overflow-y: auto !important; } </style>
The pin-set class is what I’ll apply to the sidebar content area (#pinned) when the user scrolls far enough down that the header is covered. Here is the JavaScript required for that effect. I’m using jQuery for simplicity of selectors and events:
<script type="text/javascript"> (function($) { $(function() { var int_sideheight = $(window).height() - $('#header').height() - 10; $('#pinned').css('height',int_sideheight+'px'); $(window).scroll(function() { if ($(this).scrollTop() > $('#header').height()) { $('#pinned').addClass('pin-set').css('height','100%'); } else { var int_sideheight = $(window).height() - $('#header').height() - 10; $('#pinned').removeClass('pin-set').css('height',int_sideheight+'px'); } }); }); })(jQuery); </script>
What I’m doing is checking to seel when the scrollTop() is greater than the height of the header area. If it is, then apply that pin-set class to the sidebar navigation area. If it isn’t, I’m clearing the class so that the sidebar area will always remain below the header area. The mouseover scroll bar effect is purely CSS-driven.