Pixelastic

You can cut our wings but we will always remember what it was like to fly.

IE8 ghost :after and :before pseudo elements

IE8 has a strange bug (what bugs aren't strange in IE ?) when dealing with :after and :before pseudo-elements.

I was adding a nice looking arrow after one of my elements using :after. I wanted this arrow to only display when my element was hovered, so I wrote the following code :

<a href="#">Example</a>
a {
position:relative;
display:block;
height:30px;
}
a:after {
position:absolute;
content:"";
top:0px;
right:-15px;
width:15px;
height:30px;
background:url(arrow.gif) top left no-repeat;
display:none;
}
a:hover:after {
display:block;
}

As you can see, nothing too fancy. I positionned my arrow using an empty :after element and a background image. I defaulted the arrow to hidden, and only show it when hovering the element.

IE in action

It does work pretty well in moder browsers. It also seems to work on IE8. When you hover the element in IE8, the arrow gets displayed. But it does not gets hidden when you stop hovering it.

There's a kind of ghost element that keeps getting displayed. It gets removed if you directly mouse it, or scroll your page, or alt-tab, etc. This clearly is a display artefact.

To counter this I had to write it in an other fashion (less readable in my opinion). Removing the default a:after rule and adding all properties to a:hover:after :

a {
position:relative;
display:block;
height:30px;
}
a:hover:after {
position:absolute;
content:"";
top:0px;
right:-15px;
width:15px;
height:30px;
background:url(arrow.gif) top left no-repeat;
display:block;
}

Update

It should be noted that more generally, I gets confused and create ghost elements and styling when we try to update the :after/:before properties based on a rule selecting its parent.

There seems to have a little lag/delay before the properties gets applied, and most of the time they do not.

Comments

It's super awesome when posting something like this to make a reduced test case =)

I made one for you:

http://jsbin.com/odego5/3

I couldn't get the first way to work at all in IE 8, but the second way does indeed work fine. I'll post again if I dig up more info.
Chris Coyieron 4/5/11
Chris Coyier
OK the scoop here is that you have to declare a :hover state for those links. Just do something like a:hover { cursor: pointer; } and either example will work fine. Whattyagonnado.
Chris Coyieron 4/5/11
Chris Coyier
You are right about the test case Chris, it is far more readable that way. I'll add those to my next posts.

And also, your fix is simpler than mine and could easily be added to a default CSS file to automatically fix those kind of artefacts.
Timon 5/5/11
Tim
I came here after googling for a similar problem: I added/removed a class on the parent element through javascript, but in IE8 the background on the generated content didn't update in IE8.

When I added the following line to my js, it consistently triggered the redraw:

document.activeElement.blur();

It might not always be what you want or can do, but at least it's a solution.
Ron Derksenon 16/6/11
Ron Derksen
Changing content on :hover:after also works.

Example:
a:after{content:""; display:none;}
a:hover:after{content:" "; display:block;}
timoffeion 16/7/11
timoffei
... and 8 spam blocked

Adding a comment

Leave this field empty, it is only here to defeat spam bots
Will not be published