JavaScript で要素のクラス属性を操作してスタイルを変更するような場合、IE8 には :before
/:after
擬似要素のスタイルが再描画されないというバグがある。
<p>
<a href="#" class="selected">One</a>
<a href="#">Two</a>
<a href="#">Three</a>
<a href="#">Four</a>
</p>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
$('p').each(function () {
var $links = $(this).find('a'),
i = $links.filter('.selected').eq(0).index(),
len = $links.length;
function selectItem () {
i = (len - i > 1)? i + 1: 0;
$links.removeClass('selected');
$links.eq(i).addClass('selected');
}
setInterval(selectItem, 3000);
});
</script>
たとえばこんなふうに、一定時間ごとに selected
というクラスを持つ要素が切り替わるようなスクリプトがあって、その要素の :before
擬似要素にスタイルを書く、という場合。
a:before {
background-color: silver;
content: "";
display: inline-block;
height: 1em;
width: 1em;
}
a.selected {
background-color: yellow;
}
a.selected:before {
background-color: green; /* not working in IE8 */
}
グリーンのボックスを持ったリンクが 3 秒ごとに切り替わっていくはずだけど、IE8 では :before
で生成したボックスのスタイルが更新されず、初期状態のグレーのまま変化しない。
これを更新させるには、content
プロパティの値になんらかの変更を加える必要がある。
a:before {
background-color: silver;
content: "";
}
a.selected:before {
background-color: green;
content: " ";
}
このように空文字列から空白文字に変更するか、
a:before {
background-color: silver;
content: "";
}
a.selected:before {
background-color: green;
content: "" "";
}
あるいは空文字列を追加するのでもいい。
Stack Overflow の回答 が参考になったけど、サンプルがちょっとわかりづらかった。
IE8 には :hover:before
(または :hover:after
) のスタイルが適用されない というバグがあって、:hover
になんらかのスタイルを指定することで回避できるけど、この content
上書きパターンでもいける。スクリプトによる属性の更新とホバーやフォーカスなどが重なると挙動があやしくなることもあるけど、おおむね機能してるっぽいし、正直これ以上あまり深追いしたくない…