IE hover trigger

Okay, this was unexpected.

I’ve needed to “trigger” IE’s hover states for some things (like Sons of Suckerfish in IE7… see [url=http://www.satzansatz.de/cssd/pseudocss.html#stickyhover]sticky hover though the other problem is a lack of anything happening at all on :hover if you, say, remove the sfHover stuff and use something else like PeterNed’s csshover file), but I have a page where it’s causing IE6 to collapse the height of an anchor on :hover.

A cut-down version of a page I’m working on:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <meta http-equiv="content-language" content="en">
    <title> Test IE6 :hover event </title>
    <meta name="description" content="Test abso-po'd anchor's height collapse on :hover">
    <link rel="icon" href="favicon.ico" type="image/x-icon">
    <style type="text/css">
* {
  margin: 0;
}

html, body, ul, ol {
  padding: 0;
}

[b]/*IE6*/
* html a:hover {
  visibility: visible;
}[/b]


body {
  color: #000;
  font: 100% verdana, "dejavu sans", "mgopen modata", sans-serif;
  background-color: #ededed;
}

#header {
  height: 4em;
  padding: .5em 0;
  background-color: #333;
  border-bottom: 3px solid #f90;
}

#naam {
  position: relative;
  color: #fff;
  font: bold 1.8em/2.5em futura, geneva, helvetica, arial, sans-serif; 
  text-align: center;
}
        #naam span {
          color: #9bcded;
        }
        #naam a {
          position: absolute;
          left: 0;
          top: 0;
          width: 100%;
          height: 100%;
        }
#naam {
  float: left;
  width: 364px;
  height: 50px;
}
      #naam a {
          background: url(images/scooterlogo.png) 0 0 no-repeat;
        }
    </style>

</head>
<body>
  <div id="container">
    <div id="header">
        <p id="naam">scooter*<span>verzekeren.com</span><a href="/"> </a></h1>
    </div>

    <div class="inhoud">
      <h1>IE6</h1>
    </div>
  </div>
</body>
</html>

See bolded code.

Doesn’t matter if you leave it out of the * html hack, or if you say “:hover” instead of a:hover or whatever. If you leave that bit of code uncommented, you can see in IE that if you mouse over the title, the anchor vanishes. This not only hides the image, which isn’t a huge deal, but removes a clickable area, meaning the anchor is not usable.

So, while I had been adding in the “trigger” on some sites, including the old version of this current site, I found I’m going to have to keep it very local to where I’m fixing a bug. I have seen the height-collapse of abso-po’d anchors inside a rel-po’d float before, but setting heights on :hover fixed those… not so here.

If I understand correctly then I should NOT be using this as a blanket trigger. I’m not sure here why this sets off the bug, only that it’s certainly the code doing it.

I’m not even sure what that code is trying to attempt to do – hover an empty area to make the logo image show?

I’d have to see what it is you are actually trying to do in a real website – though I’d NEVER write code that way and have never heard of this collapsing issue; though the anchor still being inline and having no content but whitespace are both known for cross-browser issues. The lack of a line-height could also be messing with you, much less the lack of a display state change on hover.

It’s also filled with other no-no’s like padding and height on the same element, separated declarations for no reason… Not that those should be causing IE issues, I’m still trying to figure out what… OH, is that supposed to be a image replacement?!?

  1. then being in #header shouldn’t that be a heading tag?

  2. shouldn’t the anchor be wrapping ALL the content of #naam so the link is usable when CSS is disabled?

Actually, hah - you are opening it as a P and closing it as a h1.

Take an axe to the pointless #header div, use the h1 (like the closing tag you were) and use a image sandbag in your anchor wrapping EVERYTHING in the A.

try this:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <meta http-equiv="content-language" content="en">
    <title> Test IE6 :hover event </title>
    <meta name="description" content="Test abso-po'd anchor's height collapse on :hover">
    <link rel="icon" href="favicon.ico" type="image/x-icon">
    <style type="text/css">
* {
  margin: 0;
}

html, body, ul, ol {
  padding: 0;
}

a:hover {
  visibility: visible;
}

/*IE6*/
* html a {
  font-size:1.5em;
}

* html a:hover {
  visibility: visible;
}


body {
  color: #000;
  font: 100% verdana, "dejavu sans", "mgopen modata", sans-serif;
  background-color: #ededed;
}

#header {
  height: 4em;
  padding: .5em 0;
  background-color: #333;
  border-bottom: 3px solid #f90;
}

#naam {
  position: relative;
  color: #fff;
  font: bold 1.8em/2.5em futura, geneva, helvetica, arial, sans-serif; 
  text-align: center;
}
        #naam span {
          color: #9bcded;
        }
        #naam a {
          position: absolute;
          left: 0;
          top: 0;
          width: 100%;
          height: 100%;
        }
#naam {
  float: left;
  width: 364px;
  height: 50px;
}
      #naam a {
          background: url(images/scooterlogo.png) 0 0 no-repeat;
        }
    </style>

</head>
<body>
  <div id="container">
    <div id="header">
        <p id="naam">scooter*<span>verzekeren.com</span><a href="#"></a></h1>
    </div>

    <div class="inhoud">
      <h1>IE6</h1>
    </div>
  </div>
</body>
</html>

actually there are two problems:

  • the space inside the <a> element: delete that and the <a> doesn’t disappear on :hover
  • the missing content for the <a> element: font-size: 1.5em fixes just that

the </h1> doesn’t impact on the overall behaviour. i’ve let it there as proof. but i’m sure Sp will correct it :slight_smile:

I think this is the problem here. i remember a similar bug.

no, it’s not it.

closing tag for <p> is O. </div> comes right after a wrong </h1>. that makes the </p> omission harmless.

as i’ve stated before, the two problems are:

  • <a href=“/”> </a> should be <a href=“/”></a>: notice no space inside the <a> element, to make it disappear on :hover
  • the lack of content for the <a> element: * html a {font-size:1.5em} solves the half-height <a> on :hover

I’m just still trying to figure out what the desired behavior IS… it makes no sense to have a non-hidden element become visible on hover… I mean what is this even supposed to do besides waste code on nothing? As written/presented it shouldn’t even be doing ANYTHING in ANY browser.

ok.

if you leave the space inside the <a> element: <a href=“/”> </a>, you don’t get the hand cursor over the <p> at all on :hover. the <a> seems to disappear.

if you remove the space inside the <a> element: <a href=“/”></a>, you get an incomplete coverage and behaviour on :hover for the <p> element.

finally, adding

/*IE6*/
* html a {
  font-size: 1.5em;
}

you get the full coverage and behaviour on hovering the <p> element.

of course, you have to try all this in ie6 :slight_smile:

You missed what I’m saying – I’m wondering why the *** you’d be putting an empty anchor over it in the first place instead of having the anchor wrapping everything and then using a sandbag for the image…

… and for the life of me I can’t figure out what the hover is even there for since that should be doing nothing. Lemme drag my crippy ass out of bed and over to my workstation and I’ll write up what I mean.

Ok, I’m still not certain what that page code is even supposed to DO – as in why it even has the hover in the first place – I’m going to assume that the image is hidden and should be shown on hover, otherwise what the **** is it even there for.

in the code we have a #header div that probably serves no purpose in the final layout, and since a </h1> is present on the first element I’m gonna treat that first section as the h1 (site logo) and drop the div/h1 pairing to a P.

#header is having a height set on it for no reason I can fathom other than trying to break the layout… much less the attempt to put a PX height anchor over a EM padded EM line-height element… so I’m going to end up converting everything to PX since for a image replacement (which I’m asusming is the point ) this would otherwise be inherently broken on large font/120dpi systems.

Basically, I’d cut the markup down to:


  <h1>
  	<a href="/">
  		scooter*<span>verzekeren.com<span></span></span>
  	</a>
  </h1>

… and yes that would replace div#header ENTIRELY…

With this for CSS:

h1 {
	overflow:hidden; /* wrap floats */
	width:100%: /* trip haslayout, wrap floats IE */
	font:bold 22px/24px futura, geneva, helvetica, arial, sans-serif;
	background:#333;
	border-bottom:3px solid #F90;
}

h1 a {
	position:relative;
	float:left;
	width:364px;
	padding:16px 0;
	text-decoration:none;
	color:#FFF;
}

h1 a:active,
h1 a:focus,
h1 a:hover {
	/* 
		IE will often not hover a anchor's children if there's
		no change to the anchor itself -- so lets change it so
		subtle nobody will notice
	*/
	color:#FFFFFE; 
}

/* sucks, but state full inheritance to nab specificity issues */

h1 a span {
	color: #9bcded;
}

h1 a span span {
	position:absolute;
	top:0;
	left:0;
	width:364px;
	height:56px;
	display:inline;  /* prevent IE hover sticking */
	background:url(images/scooterlogo.png) 0 -999em no-repeat;
}

h1 a:active span span,
h1 a:focus span span,
h1 a:hover span span {
	display:block; /* prevent IE hover sticking */
	background-position:0 0;
}

ASSUMING that anchor was originally SUPPOSED to be a image replacement… Which is a big assumption. As I said I can’t even figure out what the original code is even supposed to do or what the point of it was, even after running it locally. Since the anchor wasn’t set to visibility:hidden, why would changing it to visible do ANYTHING? (It didn’t here!)

Though it could be I’m not seeing it because here those EM fonts are too big and peeking out from under the anchor… IT also isn’t helping that #header has it’s width and padding declared in a different EM from the values set in #naam – which is why it wasn’t centered top to bottom either. Remember the rule PX image interaction forces you into PX fonts, or it’s a broken layout SOMEWHERE. This is why %/EM is for dynamic elements and px is for image replacement headers or things like buttons with a fixed size background image.

I really think though I’m missing what it is the page is even supposed to be doing. I’m not talking ‘behavior’ as in the :hover – I’m talking what is that even supposed to be DOING (as in the entire page example). That’s just horrid code. Paragraph for nothing, anchor without content, likely a #header div for nothing… SP either cut too much code out in this example or not enough – either way ASSUMING that’s supposed to be a image replacement (which I don’t think it is) it’s a train wreck.

i assume the mark-up you propose is this one?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <meta http-equiv="content-language" content="en">
    <title> Test IE6 :hover event </title>
    <meta name="description" content="Test abso-po'd anchor's height collapse on :hover">
    <link rel="icon" href="favicon.ico" type="image/x-icon">
    <style type="text/css">
h1 {
	overflow:hidden; /* wrap floats */
	width:100%: /* trip haslayout, wrap floats IE */
	font:bold 22px/24px futura, geneva, helvetica, arial, sans-serif;
	background:#333;
	border-bottom:3px solid #F90;
}

h1 a {
	position:relative;
	float:left;
	width:364px;
	padding:16px 0;
	text-decoration:none;
	color:#FFF;
}

h1 a:active,
h1 a:focus,
h1 a:hover {
	/* 
		IE will often not hover a anchor's children if there's
		no change to the anchor itself -- so lets change it so
		subtle nobody will notice
	*/
	color:#FFFFFE; 
}

/* sucks, but state full inheritance to nab specificity issues */

h1 a span {
	color: #9bcded;
}

h1 a span span {
	position:absolute;
	top:0;
	left:0;
	width:364px;
	height:56px;
	display:inline;  /* prevent IE hover sticking */
	background:url(images/scooterlogo.png) 0 -999em no-repeat;
}

h1 a:active span span,
h1 a:focus span span,
h1 a:hover span span {
	display:block; /* prevent IE hover sticking */
	background-position:0 0;
}
    </style>

</head>
<body>
   <h1>
  	<a href="/">
  		scooter*<span>verzekeren.com<span></span></span>
  	</a>
  </h1>
</body>
</html>

the reason i’m asking it’s because the code you provided has some display issues in ie6-7.

Sorry guys, while I was typing into my first post and editing here as I went, the </h1> was left in there (I was changing from the real code to a p, but the actual page is </p> not </h1>). http://stommepoes.nl/Scooterverzekeren/scooter2/ie6.html The original-original version had an h1 there. Still, I should have run my cut-down version through the validator anyway.

The reason there are double declarations for some elements is because I’m doing a layered-mobile-then-desktop setup, so there are two stylesheets on the real dev version. I wanted to make sure that I kept to that since IE6 does indeed care sometimes if some property is declared separately.

the space inside the <a> element: delete that and the <a> doesn’t disappear on :hover

Not true. My link above, I’ve removed the space for Opera testing, and I get a collapse (see font-size below).
However the anchor is then completely content-less… not all Operas will click on a content-less link. A space character counts as content. With non-anchor Gilder-Levin I did not have a space in the <span></span>

*edit this was with Opera 9+ and it was with destination links… testing with Opera 10+ shows the link working ok without the space, both with keyboard and mouse. I’ll have to see if the old rule still holds for destination links. If all browsers will still keyboard to the content-less link then I can consider removing the space (esp if it’s causing various IE bugs!).

the missing content for the <a> element: font-size: 1.5em fixes just that

I’ll see if that does it… yes and no. Adding a font-size in and of itself does nothing (as a trigger) but it must be as large as you have it, 1.5em in this case, in order to be at least as tall as the image. Adding a font-size of 1em and removing the space shows collapse of half the anchor (collapses down to 1em likely). Removing the visibility trigger removes the problem without needing font-size set on the abso-po’d anchor.

Since the anchor wasn’t set to visibility:hidden, why would changing it to visible do ANYTHING? (It didn’t here!)

It’s an old trick: you can state certain things on states or elements and it does a trigger on IE (not haslayout, but something more insidious).
To see it in action, copy the code as-is from the Sons of Suckerfish page (linked in first post) but then remove the Javascript in the head entirely. Then view in IE7. Dropdowns won’t drop down. With the Javascript in place, some people would get a “ghost-hover” or sticky dropdowns in IE7 (dropdown remained onscreen after mouse-off). Setting visibility, background-colour, font-weight, and a handful of other properties can fix this. Also “background: url(#);” does it too : )

though the anchor still being inline…

Now I do remember you explaining that while setting position: absolute on an inline puts it in block context (which is why I don’t do the whole display: block; float: left; or display: block; position: absolute; stuff), IE doesn’t consider it an actual state change. I’m not sure I want to add in what is redundant to other browsers IF I can leave it and get my block behaviour visually in IE anyway.

  1. then being in #header shouldn’t that be a heading tag?

No, “header” is a holdover name from the original-original source code: a box at the top of every page (in ARIA it would be called “banner” role) and no, it’s a box who ultimately is holding many elements and holds a bottom-border, background colour and background image, and contains the logo which is not a header tag on most pages (the name of the page’s content is the h1). When you have multiple elements who are visibly contained inside a styled container… you need a styled container.

  1. shouldn’t the anchor be wrapping ALL the content of #naam so the link is usable when CSS is disabled?

No. Clickable logos going to redundant Home page is a sighted-user convention which personally I believe has no place on a web page (but is demanded by convention nowadays) and certainly over-redundant when using a text browser (there’s usually a link to home in the menu, omitted here because the content is not finished). Here, the anchor is replacing the span in typical image-replacement.

… and yes that would replace div#header ENTIRELY…

IF this were all that were going up there, then yes, but NOT on a page with a bunch of elements who need a single wrapper with styles. I left it in the cut-down version because it is enclosing the floated p and I needed to be sure it did not have any cause to the bug.

Since on Desktop the logo sits to the left (along with future tagline) and utility menu will sit to the right, 100% width on the logo-name are not useful here.

i have to side with ds60 on this one.

redundant or not, you are using a semantic element ONLY for presentation.

when there is only user style css (default style), your <a href=“/”> </a> has no usability, no meaning, no purpose, no visibility, because of it’s white space content.

it gains one the moment you apply your css on it. that makes it a hook for style. the wrong way.

Hi,

The real trigger for the bug is the percentage height on the absolute anchor. IE6 always has had problems with percentage measurements from absolute elements when based on the relative parent size and is the reason that my equal column techniques give IE6 an impossibly large value and then hide the overflow.

IE just wont base a percentage height properly on the absolute anchor and although it partially gets it right the reflow on the anchor causes it to forget and the height collapse.

Simplest example.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style>
p {
    height:500px;
    background:red;
    position:relative
}
.test {
    position:absolute;
    left:0;
    top:0;
    width:100%;
    height:50%;
    background:green
}
a:hover {
    background:blue
}
</style>
</head>
<body>
<p><a class="test" href="#">test</a></p>
</body>
</html>


A fullproof solution would be to size a parent elemetn instead but means adding mark up.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style>
p {
    height:500px;
    background:red;
    position:relative
}
b {
    position:absolute;
    left:0;
    top:0;
    width:100%;
    height:50%;
}
a{
    display:block;
    background:green;
    height:100%;
}
a:hover {
    background:blue
}
</style>
</head>
<body>
<p><b><a href="#">test</a></b></p>
</body>
</html>



In your example you could get away without adding extra elements but would need to set the height in pixels which you are doing for the parent anyway.


#naam a {
    position: absolute;
    left: 0;
    top: 0;
    /*width: 100%;
    height: 100%;*/
[B]    width: 364px;
    height: 50px;[/B]
}


Note that if the relative parent had no height defined (e,g, content height) then IE6 will not match an absolute elements percentage height to it at all (and as I said the reason for the fix in my absolute columns examples.)

i have to side with ds60 on this one.

redundant or not, you are using a semantic element ONLY for presentation.

when there is only user style css (default style), your <a href=“/”> </a> has no usability, no meaning, no purpose, no visibility, because of it’s white space content.

it gains one the moment you apply your css on it. that makes it a hook for style. the wrong way.

Understandable argument. The solution could be so:

<p id=“naam”><a href=“/”>scooter<span>verzekeren</span><span class=“gl”></span></a></p>
p {
position: relative;
same styles;
}
p span {
the colour;
}
p span.gl {
position: absolute;
etc…
}

But, IE may not correctly use the coords of the span.gl because the positioned parent isn’t a direct parent, only an ancestor (bug). And if the span.gl is to sit above the anchor, I don’t know if it would be clickable still in all browsers even though it’s a child (should be?).

Paul: wondering why IE6 is doing ok if I remove the trigger? Or is the trigger helping the %-height-abso-po’d-el’s bug?

probably because then the algorithm is simpler and there is no need to take care of a re-flow on hover. It’s similar to the peek-a-boo bugs and percentage margin bugs that all failed when an anchor was hovered and a property targeted.

That’s why my fix with the b element works because the b element can’t be hovered and is left alone.

The same bug was evident in the link block hover quiz we did years ago.

Really dumb trick IMHO – but then there’s a reason I use csshover3.htc instead of suckerfish – NOT that I can figure out what suckerfish has to do with a page heading.

Though my last example assumed you were trying to make a hover state, not use that as a fix… If all you’re doing is gilder-levin over that, you made it WAY more complex than need be, and broken to boot:

PX over EM == /FAIL/.

I changed it to a h1 in the following example, but if all you are doing there is gilder-levin on a image it doesn’t even need a float! No joke! If you have a menu on the other side, you float that then use a negative margin to pull it up into place. Finally there IS the pointer issue on hover which can rear it’s ugly head… in IE5 only. Who cares about fixing it in IE5? Well, I do since it’s a one line fix; Cursor:hand;

So this is how I’d do that:

http://www.cutcodedown.com/for_others/stommepoes/scooterh1/template.html

You know the deal on me leaving the directory accessibile:
http://www.cutcodedown.com/for_others/stommepoes/scooterh1/

Valid XHTML 1.0 Strict, Would be valid CSS 2.1 if not for the expression (for min-width) and IE specific cursor property, and tested working perfect all the way back to IE 5.01

Markup is a h1 A SPAN SPAN as I listed up above, you can see I added a ul to ride up into place to show how to do the content on the right. (your ‘utility menu’ for example).

On the CSS because of the image interaction we’re forced into PX on BOTH the h1 and ul, negative top margin on the floated UL rides it up over the h1, with no hover oddities in any version of IE. You can see I avoid declaring heights on anything other than the UL (which is a taller height than it’s child elements) and the span that’s used as a image replacement. Everything else is figured using line-height plus padding, which is just part of why it works all the way back to IE 5.0.

No steenkin div#header needed. You want the whole thing as a anchor, make the whole thing an anchor NOT JUST the image replacement!

– edit –
Oh, I redid the image too so that 1) it’s the full height of the replacement should a different font or firefux’s dimwit text resize try to peek out, and to 2) remove the horrible ‘dithering for no reason’ whatever program you saved it from was adding… Well, and to take it from 8k to 3k.

Really dumb trick IMHO -

Actually it’s quite a clever little trick :slight_smile:

The trick has nothing to do with the suckerfish and is a very old IE6 bug (and also occasionally present in Ie7 when used in situations like li:hover ul).

When you try to action a change on a child of an anchor when hovering IE6 will only action the change if some property on the anchor is also changed. You could change the background or a border but of course that would mean changing the look of the element.

visibility:visible does not change the look of the element at all and is the perfect fix and I’ve been using it since I first discovered it way back in about 2003 without problem.

The bug that Mallory was experiencing was not triggered purely by the visibility:visible fix but by the percentage bug in conjunction with an anchor property being changed. It would have happened had the background been changed to a color as shown in my previous examples.

Here is the basic example.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type="text/css">
/* without this IE6 won't change the background color of the span*/
#test a:hover{visibility:visible}

#test a:hover span{background:blue;color:#fff}
</style>
</head>
<body>
<p id="test"><a href="#">Testing <span>this is the span</span></a></p>
</body>
</html>


Without the fix IE6 will not work at all. You would need to change some other property on hover which is not always feasible if you don’t want the look of the element to change.

Ok, I think what was confusing me then was the complete lack of a hover state OTHER than that fix… which made it completely pointless. Why apply a hover state fix to something that didn’t have a hover state?

Why apply a hover state fix to something that didn’t have a hover state?

Yes, I see what you mean.:wink:

I don’t think the blanket fix that Mallory was using is a good idea anyway and the visibility:visible rule should be specifically targeted to the element concerned.