Css hover in Internet Explorer

September 8, 2007

CSS is tricky or Internet Explorer has a lack of support?

Many of you there who work daily with CSS designing have reach a point where they were stuck. The most times it was because something strange ti was happening in Microsoft’s propertary browser, the well known Internet Explorer. Many of the W3C standards regarding the CSS are ignored in internet explorer.

One of the issues is the lack of support for the hover characteristic. Some times we can put an achor link over a whole element be it a div, a list element, a span or whatever. This way we get rid of some the problems regarding hovers. But that’s not possible always.

#menu {

 LINE-HEIGHT: 1.2em;

    background-color: #dfed6b;

}

#menu UL {

 WIDTH: 750px;

 BACKGROUND-COLOR: #dfed6b;

}

#menu LI {

 FLOAT: left;

 WIDTH: 10%;

 POSITION: relative;

 BACKGROUND-COLOR: #dfed6b;

 BORDER-RIGHT: #cbd0a1 1px solid;

 MIN-WIDTH: 5em;

 HEIGHT: 3.1em;

}<div id="menu" class="csshover">

      <ul id="menuList" >

<li id="menuHome">

              <div class="menuProprT">

                <div class="menuProprM">

                  <div class="menuProprB">

                    <a class="linkMenu" href="/home" >Home page</a>

                  </div>

                </div>

              </div>

            </li>

 </ul>

</div>

This snippet here is a case of a menu bar. A classic list with specific settings for displaying a menu. Everything going good until here. Every list element is a menu item and has within it an anchor. Now, we want to add a hover effect to each menu item, something like changing the background image or text font/style.

#menu LI:hover { BACKGROUND-COLOR: #d3e066;}

Now we have a hover effect over each li element. But that won’t work in Internet Explorer though. and that’s not because we did something wrong but because that’s how Internet Explorer behaves. Dont support hte hover properties for html elements other than the standard <A>. Anyways, thanks to Peter Nederlof, there is a work-around. We’ll add the class “csshover” to our html element that needs to support hover. He wrote some javascript snippets that force IE to respect hover while loading the CSS file. Above are the mentioned snippets:

<attach event=”ondocumentready” handler=”parseStylesheets” />

<script language=”JScript”>

/**

 *	HOVER - V1.11.040203 - whatever:hover in IE

 *	———————————————

 *	Peterned - http://www.xs4all.nl/~peterned/

 *	(c) 2004 - Peter Nederlof

 *

 *	Credits  - Arnoud Berendsen

 *		for finding some really -sick- bugs

 *

 *	howto: body { behavior:url(”csshover.htc”); }

 *	———————————————

 */var currentSheet, doc = window.document;

//	keeps the dropdown menu IDs

var ddMenuIDs = new Array();

function findDdMenus() {

        var aTmp = getElementsByClassName(”csshover”, element.document, “div”, function(oM) {

                ddMenuAdd(oM.id);

        } );

};

function ddMenuAdd(ddMenuID) {

        if ( typeof(ddMenuID) == “undefined”) return;

        ddMenuIDs[ddMenuIDs.length] = ddMenuID.replace(/List/, “”);

};

function parseStylesheets() {

        findDdMenus();

 var sheets = doc.styleSheets, l = sheets.length;

 for(var i=0; i<l; i++)

 	parseStylesheet(sheets[i]);

}

 function parseStylesheet(sheet) {

 	var l, rules, imports;

 	if(sheet.imports) {

 		imports = sheet.imports, l = imports.length;

 		for(var i=0; i<l; i++)

 			parseStylesheet(sheet.imports[i]);

 	}

rules = (currentSheet = sheet).rules, l = rules.length;

 	for(var j=0; j<l; j++) parseCSSRule(rules[j]);

 }

function parseCSSRule(rule) {

 	var select = rule.selectorText, style = rule.style.cssText;

if ( style.replace(/ /, “”) == “” ) return;

var ddMenuID, Found = 0;

                for (var t=0; t<ddMenuIDs.length; t++) {

                        if (select.indexOf(ddMenuIDs[t]) != -1) {

                        Found = 1;

                        ddMenuID = ddMenuIDs[t];

                        break;

                        }

                }

                if (!Found) return;

if(!(/(^|s)(([^a]([^ ]+)?)|(a([^#.][^ ]+)+)):hover/i).test(select)) return;

var newSelect = select.replace(/(.([a-z0-9_-]+):hover)|(:hover)/g, ‘.$2onHover’);

 	var hasClass = (/(.([a-z0-9_-]+):hover)/g).exec(select);

 	var className = (hasClass? hasClass[2]:”) + ‘onHover’;

var affected = select.replace(/:hover.*$/g, ”);

                eval(’affected = affected.replace(/#’ + ddMenuID + ‘([ ]+)/i, “”)’);

var elements = getElementsBySelect(affected, ddMenuID);

currentSheet.addRule(newSelect, style);

 	for(var i=0; i<elements.length; i++)

 		new HoverElement(elements[i], className);

 }

function HoverElement(node, className) {

 if(!node.hovers) node.hovers = {};

 if(node.hovers[className]) return;

 node.hovers[className] = true;

 node.attachEvent(’onmouseover’,

 	function() { node.className += ‘ ‘ + className; });

 node.attachEvent(’onmouseout’,

 	function() { node.className =

 		node.className.replace((new RegExp(’s+’+className)),”); });

}

function getElementsBySelect(rule, ddMenuID) {

 var parts, nodes = [doc.getElementById(ddMenuID)];

 parts = rule.split(’ ‘);

 for(var i=0; i<parts.length; i++) {

 	nodes = getSelectedNodes(parts[i], nodes);

 }	return nodes;

}

 function getSelectedNodes(select, elements) {

 	var result, node, nodes = [];

 	var classname = (/.([a-z0-9_-]+)/i).exec(select);

 	var identify = (/#([a-z0-9_-]+)/i).exec(select);

 	var tagName = (/^[a-z0-9]+/i).exec(select.toUpperCase()) || ‘*’;

 	for(var i=0; i<elements.length; i++) {

 		result = elements[i].getElementsByTagName(tagName);

 		for(var j=0; j<result.length; j++) {

 			node = result[j];

 			if((identify && node.id != identify[1]) || (classname && !(new RegExp(’b’ +

 				classname[1] + ‘b’).exec(node.className)))) continue;

 			nodes[nodes.length] = node;

 		}

 	}	return nodes;

 }

function getElementsByClassName(clsName, parentEle, tagName, fn) {

 var found = new Array();

 var re = new RegExp(’b'+clsName+’b', ‘i’);

 var list = parentEle.getElementsByTagName(tagName);

 for (var i = 0; i < list.length; ++i) {

 	if (list[i].className.search(re) != -1) {

 		found[found.length] = list[i];

 		if (fn) fn(list[i]);

 	}

 }

 return found;

}

</script>

What you have to do for that to work: Just save the javascript snippets as “csshover.htc” and in your html file, into the head section add this

<style type="text/css">

body { behavior:url("csshover.htc");
</style>

Everything should be working now. Enjoy your hover!

Note: The csshover.htc need to be in the correct folder related to your html page that uses it.

 

Post a comment

Name (required)

Mail (will not be published) (required)

Website

*
To prove you're a person (not a spam script), type the security text shown in the picture. Click here to regenerate some new text.
Click to hear an audio file of the anti-spam word