An IE6-compatible solution for :hover

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:

  1. 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.
  2. 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').

Bookmark and Share

Popularity: 69% [?]

Related Posts

Education: the rational ability to make sense of the chaotic present through the abstract wisdom of the past.

-- Victor Davis Hanson

Comments 19

  1. Conficio wrote:

    Cool feature and certainly a cool solution. I’m becoming a fan of your blog ;-)
    K<o>
    Busy, providing technical support to non technical users of OpenOffice,org

    Posted 31 May 2007 at 5:56 pm
  2. kangax wrote:

    Just a bit simplified version…

    # Event.observe(window, ‘load’, function() {
    # if (Prototype.Browser.IE)
    # {
    # $$(’table.hover tr’).each( function(el) {
    # el.observe(’mouseover’, function(e) {
    # Event.element(e).addClassName(’hover’);
    # });
    # el.observe(’mouseout’, function(e) {
    # Event.element(e).removeClassName(’hover’);
    # });
    # });
    # }
    # });

    Posted 08 Jun 2007 at 11:40 am
  3. brian wrote:

    I didn’t realize Prototype had a Browser object. Good tip on that, and on using the extended element classes instead of calling Element methods.

    Posted 10 Jun 2007 at 1:47 pm
  4. Scott wrote:

    Can anyone provide a simple working version of this work around?
    I can not seem to get the page to work.

    Thanks in advance.

    Posted 12 Jun 2007 at 11:22 am
  5. brian wrote:

    1. Add class=”hover” to your table tag. Without this, the script won’t do anything. The “hover” behavior is applied only to those tables with the “hover” class.

    2. Add a tr.hover declaration that does something to your CSS (such as “background-color:grey”). The tr.hover declaration in your CSS should reflect the style you want to apply when hovering over your table rows.

    3. Reference the Prototype library from your HTML file (script src=”…”). This is a core dependency.

    Posted 12 Jun 2007 at 3:40 pm
  6. Mark Perkins wrote:

    Nice solution… but only if you are using prototype for some heavy lifting javascripting on your site anyway. Not sure if 40K of javascript is really worth it for just a bit of table striping.

    Just give ie6 users a slightly degraded browsing experience - that way they may slowly realise that changing browsers is actually worthwhile and we may eventually be rid of these issues.

    Posted 22 Sep 2007 at 2:23 pm
  7. brian wrote:

    I agree that using Prototype just for hovering support in IE6 is not worth it — unless that hovering support is critical otherwise (which is doubtful). Then again, if you’re already using Prototype (which I usually am)… :)
    As well, the same techniques can be done with any JS library — or none (plain ‘old JS).

    Posted 22 Sep 2007 at 10:14 pm
  8. Livingston Samuel wrote:

    the simple solution that will fix the hover issue in Internet Explorer 6

    http://blog.delivi.info/javascript/hover-for-non-anchor-elements-in-ie6/

    Posted 20 Feb 2008 at 9:48 am
  9. Femi wrote:

    For me onmouseout events are not working if I using span tag

    Posted 10 Apr 2008 at 7:45 am
  10. chrisff wrote:

    why not do the browser test before adding the event?

    Posted 12 May 2008 at 7:34 pm
  11. brian wrote:

    Um, good point. ;)

    Posted 12 May 2008 at 9:36 pm
  12. Daisy wrote:

    Hey guys,My name is Daisy and I’m new to web programming. I’m having this problem with IE6. My client really wants that the color of the table change when someone put the mouse over it, even in IE6 (he says it is the browser the most of his clients use) Well I’ll used the code the guy suggested between the tags in the beggining of my html code. But I really don’t know how to apply it to my table (wich is very partitioned with some php code and mysql applies inside it. if someone can help, i would be grateful ^_^

    the script

    Event.observe(window, ‘load’, function() {
    if (Prototype.Browser.IE)
    {
    $$(’table.hover tr’).each( function(el) {
    el.observe(’mouseover’, function(e) {
    Event.element(e).addClassName(’hover’);
    });
    el.observe(’mouseout’, function(e) {
    Event.element(e).removeClassName(’hover’);
    });
    });
    }
    });

    the table

    echo "";

    while ($aux1 = mysql_fetch_array($res1)){

    $cor = $aux1['d_nome'];

    $combustivel = $aux1['cm_nome'];

    if ($aux1['f_fotos'])

    //verifica a existencia de fotos no cadastro

    $auxFoto = $aux1['c_idcarro'];
    $queryAuxFoto = mysql_query(”select count(id_foto) as count from fotos where id_carro = $auxFoto”);
    $nrAuxFoto = mysql_fetch_array($queryAuxFoto);

    if($nrAuxFoto['count']){
    $queryFoto = mysql_query(”select foto from fotos where id_carro = $auxFoto group by id_carro order by foto asc”);
    $dadosFoto = mysql_fetch_array($queryFoto);

    //while ($dadosFotos['foto'] = $queryFoto)
    $srcFoto = str_replace(”fotos/”, “fotos/t”, $dadosFoto['foto']);

    $foto = “http://www.meuautonovo.com.br/”.$srcFoto;
    } else {
    $foto = “imagens/estoque/vazio.gif”;
    }
    echo …

    “;

    Posted 13 Aug 2008 at 7:01 pm
  13. brian wrote:

    @Daisy,

    You seem to have added the JavaScript properly. Two things to check:

    1) Are you also including the Prototype javascript library (http://www.prototypejs.org/)?

    2) Are you adding the CSS class “hover” to your table (as in <table class=”hover”>)?

    Posted 14 Aug 2008 at 1:16 pm
  14. Christine wrote:

    Thanks for this function. I needed to exclude the first tr in the table as it contained headers. I thought I’d post the code in case it would help anyone else.

    Event.observe(window, 'load', function() {
    	if (Prototype.Browser.IE) {
    		var f=$$('table.hover tr');
    		f.shift();
    		f.each( function(e) {
    			Event.observe(e, 'mouseover', function() {
    				Element.addClassName(e, 'hover');
    			});
    			Event.observe(e, 'mouseout', function() {
    				Element.removeClassName(e, 'hover');
    			});
    		});
    	}
     });
    
    Posted 13 Feb 2009 at 5:21 pm
  15. brian wrote:

    Thanks for sharing the code, Christine!

    Posted 13 Feb 2009 at 9:49 pm
  16. mukesh wrote:

    Hi!

    how will I use this code to my html page please suggest me. I am just a beginer to javascript. So where this css and this javasript will be used and how please suggest me with example.

    Thanks!

    Posted 13 Mar 2009 at 4:38 am
  17. brian wrote:

    Simply put…

    # Include the CSS code as shown at the top of the blog post (in your existing CSS file).
    # Include the Prototype JavaScript library in your HTML page (www.prototypejs.org) (typically in the HTML header).
    # Include the JavaScript as shown in the blog post (under “Problem #3″) at the bottom of your HTML page.

    If you don’t know how to incorporate CSS or JavaScript into an HTML page, I’d suggest you research those first before trying to implement the code in this blog post.

    Posted 13 Mar 2009 at 7:51 am
  18. Nicusor wrote:

    On the last piece of code (#3) you put the last ) in the wrong place… it should be on the previous row.

    Posted 11 Nov 2009 at 4:27 am
  19. brian wrote:

    Thanks — fixed!

    Posted 19 Nov 2009 at 10:09 pm

Post a Comment

Your email is never published nor shared. Required fields are marked *