Bjørn Enki’s web design blog

Opacity (hasLayout) in Internet Explorer on expanded :hover elements

Although there are several workarounds for Internet Explorer's known problems with opacity, I recently ran into a new issue when trying to create a semi-transparent drop-down menu for a client using the css :hover pseudo-class.

Opacity (hasLayout) in Internet Explorer on expanded :hover elements

I recently had the task of converting a client's old, pure JavaScript drop-down menu into CSS/PHP. This was done for several reasons, including creating a valuable internal link structure, dynamic menu contents depending on login status, and to allow the fading in (to 80% visibility, from invisible) of menu items to work in all modern browsers as well as Internet Explorer.

The problem

In a short amount of time I had the new CSS driven drop-down menu working as intended in all popular non-IE browsers (with the help of  mootools to fade items in on :hover).  The problem however, as usual, had to do with Internet Explorer. Upon further investigation, the change in opacity of any first, second or third level <ul> to anything less than 100% was causing any children elements' :hover effects not allow their children <ul> elements to appear.

This is probably pretty confusing, and may be better demonstrated with some code:

<div id="ddmenu">
<ul class="ddul1">
<a href="#">PRODUCTS</a>
<ul class="ddul2">
<li><a href="#">Product 1</a></li>
<a href="#">Product 2</a>
<ul class="ddul3">
<li><a href="#">Product 2 Gallery</a></li>
<li><a href="#">Product 2 Specifications</a></li>
<a href="#">OTHER</a>

You are probably familiar with code similar to that above in creating your own drop-down menus. As you might expect, with a little CSS the only visible "button" in this particular menu is "PRODUCTS". Hovering on PRODUCTS would cause the child "ddul2" <ul> to appear, and hovering on "Product 2" would cause the child "ddul3" <ul> to appear.

The problem appears to be that if, for example, the "ddul1" above is anything less than fully opaque, IE triggers 'hasLayout' for the element, and it's children ("ddul2") will never appear.  Likewise, if "ddul1" is fully visible so that "ddul2" appears when hovering over PRODUCTS, but "ddul2" is anything less than fully visible, "ddul3" will not appear when hovering over "Product 2". I hope this makes sense.

This seems to be because in order to lower opacity to anything under 100%, IE must first turn on the proprietary 'hasLayout' property for the element in question - breaking the expected drop-down behavior.

I didn't spend time figuring out exactly why hasLayout breaks this behaviour, but basically, if you want an element's children to properly appear on :hover in IE, the element must be 100% visible.

A workaround

After trying to figure out the problem for a while, a quick workaround I came up with was to make the background of each parent <ul> transparent and 100% visible, but instead apply the 80% opacity fade-in to child <a> elements. As the problem is that a parent with 'hasLayout' cannot display expanded children on :hover, keeping the <ul> itself 0% opaque and instead fading the child <a> elements, nothing of :hover value ever obtains the 'hasLayout' property - just the <a> elements. This does, unfortunately, result in a bit more work for the browser (causing each <a> to fade from 0 to 80% simultaneously, rather than just fading in the parent <ul>), but it still looks perfect.

Please let me know if you have any questions or would like any clarifications, or if you know of a better  solution or way around this problem!

Posted May. 26, 2009 at 8:31 pm under: website development, css, web browsers, ie6


Bjørn Enki, Dec. 9, 2010 at 9:15 pm
Awesome! Glad to hear that it helped someone--thanks for the comment!
tBone, Dec. 9, 2010 at 9:06 pm
very helpful! I spent hours trying to workout why IE's doing this. thanks heaps!
Leave a response!