Monday, May 09, 2011

Oh the Scrollable Fixed Element in IE6!

After two years of not writing a post, it's funny that I'm writing about IE6. For goodness sakes, it's 2011! The good news is that there's a really concerted effort to encourage people to move away from IE6. Yes, it's not secure. Yes, it doesn't support HTML5. Yes, it has huge memory leaks, but IE6 still persists.

Look at Internet Explorer 6 Countdown. Look closely at Asia. As of this writing, 24% of South Korean users use IE6 and look at China. 35%! These are not insignificant numbers. If you do any business in Asia, IE6 is still an important browser to support.

Which takes me to today. At Yahoo!, we have graded browser support. Which means that we degrade gracefully to support "lower" end browsers. For example, if we're going to support HTML5 rounded corners via border-radius, they'll appear nice and round in Firefox 3.5+, Google Chrome and Safari but not in IE6, IE7 or IE8. But sometimes, there are compelling reasons to support a feature that's not natively supported in a browser. Take the CSS property
position with the value fixed.

It's an incredibly useful property. You can fix an element to the page and all the other elements scroll past it. It's great for using as a docked element at the top or the bottom of the page. Unfortunately, it doesn't work in IE6, but thankfully, people like Ryan Fait has come up with a nice CSS solution. The general idea is that if you want your element to be fixed, you make it an absolutely positioned element. A fixed - like an absolutely positioned element - takes the element out of the document flow. Then, all the other elements - those that aren't fixed - are relatively positioned. If you provide the containing body with a height of 100%, voila! You have an instant fixed element working in IE6. Congratulations and thank Ryan!

Sometimes though, you want to do a little bit more with a fixed element. "Ah, a fixed element is dull, dull, dull and it doesn't impress anyone." So to impress even your dog ( or whatever pet you have ), you'll hide and then show the element after you scroll down the page and then you'll reverse the process when you scroll up. In fact, it's exactly like what Uxmatters does, but ours will work in IE6.

Here's the example. Open that in another window. Scroll down and at 250px, you'll see the banner appear. Scroll up and it'll disappear. Now view the source. The JavaScript is near the end and is pretty simple. We'll use our trusty YUI 3.3.0 with the "node" and "event" modules.

There are a couple of key points. The first is that we show the fixed banner when the scrollTop position is greater than the SHOW or trigger position which in our case is 250px. The second is how we calculate scrollTop. For non-IE6 browsers, we use the YUI DOM method docScrollY() which returns an integer value of how much we've vertically scrolled the page. For IE6, we get the "scrollTop" from the IE6Wrapper element which is the relatively positioned element or in other words, the element that isn't fixed. ie6Wrapper.get(SCROLL_TOP) retrieves the distance between the top of the object and the topmost portion of the content currently visible in the window.

Notice how we determine scrollWindow. We test - using Y.UA.ie - to determine whether we're using IE6 and if so, scrollWindow is a reference to the ie6Wrapper. Otherwise, it's Y.config.win ( this is in fact the reference to the active window attached to each YUI instance. You can use "window", but it's recommended that you use Y.config.win. Dav Glass discusses that here. ). Now, because the scrollWindow is a reference to the ie6Wrapper or to Y.config.win, we can simply use a single "on" method to attach the "scroll" event.

Feel free to use this. Hopefully, it won't be another two years before I post something. Good day.