Something I like to incorporate on web sites with tables is automatic background highlighting of the row that the mouse is hovering over. This is easy to do with CSS:
table.hover tr:hover { background-color:#ffffcc; }
All you need to do is give your table
tag the hover class, and your mouseover hover background color works!
In all browsers except IE6, of course. IE6 only supports the :hover
pseudo-class on anchor () tags. (There’s lots of other things that IE doesn’t support or supports wrong, but that’s a story for another day.)
How can we get IE6 to hover our table rows? By using a little JavaScript and the Prototype library. Our solution requires two steps:
- Write some code to automatically detect mouseover and mouseout events on table rows, applying and removing a CSS class to the rows as the events occur.
- Add the CSS class to our CSS file.
First we’ll add a tr.hover declaration to our CSS.
table.hover tr:hover, table.hover tr.hover { background-color:#ffffcc; }
Notice that I kept the table.hover
parent selector; this is important, as we’ll use that to ensure we only apply our hover code to table rows in tables that have the hover
class.1
To get the class added (and removed) from our table rows, we use Prototype to find all elements that match the CSS selector table.hover tr, and for each one, hook a function to the onmouseover and onmouseout properties.
$$('table.hover tr').each( function(e) { e.onmouseover += function() { Element.addClassName(e, 'hover'); }; e.onmouseout += function() { Element.removeClassName(e, 'hover'); } });
Problem #1: The code above is applied to all browsers. We only need it applied to versions of IE prior to 6.0. A simple hack for this was found at Ajaxian, and is added below.
if (!window.XMLHttpRequest) { $$('table.hover tr').each( function(e) { e.onmouseover += function() { Element.addClassName(e, 'hover'); }; e.onmouseout += function() { Element.removeClassName(e, 'hover'); } }); }
Problem #2: What if our event model already declared an event on the onmouseover or onmouseout properties? The script above would clear any existing event handlers. The solution is to use Prototype’s Event.observe method to hook the functions.
if (!window.XMLHttpRequest) { $$('table.hover tr').each( function(e) { Event.observe(e, 'mouseover', function() { Element.addClassName(e, 'hover'); }); Event.observe(e, 'mouseout', function() { Element.removeClassName(e, 'hover'); }); }); }
Problem #3: If the JavaScript runs before the page loads, it may not apply the event handlers to our table. This is also resolved by using Event.observe to run the above code only after the window loads.
if (!window.XMLHttpRequest) { Event.observe(window, 'load', function() { $$('table.hover tr').each( function(e) { Event.observe(e, 'mouseover', function() { Element.addClassName(e, 'hover'); }); Event.observe(e, 'mouseout', function() { Element.removeClassName(e, 'hover'); }); )}; )}; }
There you have it — a :hover hack for IE6 that doesn’t break IE7 or Firefox. It should work with all other modern browsers, though some old browsers may have issues with it. If you know of any browsers which break with this solution, let me know.
1 The use of the class name hover caused a problem when including YUI’s Button CSS code. In their CSS, they have a CSS selector for .yuibutton.hover
. Apparently, IE6’s issue with these selectors caused my entire table to pick up the CSS from .yuibutton.hover
. To fix this, I renamed YUI’s CSS selector to .yuibutton.yuihover
and updated their JavaScript (just search/replace 'hover'
with 'yuihover'
).