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

25 comments to An IE6-compatible solution for :hover

  • 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

  • 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’);
    # });
    # });
    # }
    # });

  • 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.

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

    Thanks in advance.

  • 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.

  • 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.

  • 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).

  • Femi

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

  • chrisff

    why not do the browser test before adding the event?

  • Daisy

    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 ...

    “;

  • @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”>)?

  • Christine

    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');
    			});
    		});
    	}
     });
    
  • Thanks for sharing the code, Christine!

  • mukesh

    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!

  • 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.

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

  • If you’re using jQuery, this is a plugin that just purely implement the pseudo class :hover on ie6 for every elements. It works exactly like any other browser and you don’t need to change your code. Just loading the plugin. For me the best and fastest solution.
    http://plugins.jquery.com/project/ie6hover

  • Hello
    Code you have been inspired.
    But while you apply the code, you have made my own jquery code.

    ===================================================================

    $(document).ready(function (){

    $(“table.t1 tbody tr”).each(function(){

    $(this).hover(function(){
    $(this).addClass(‘hover’);
    },function(){
    $(this).removeClass(‘hover’);
    });

    });

    });

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>