IE は runtimeStyle より !important のほうが強い
IE は CSS で !important が指定されていると、runtimeStyle が機能しなくなります。
デモ
IE6〜IE8 では、赤い "this is test" が表示され、その他のブラウザでは青く表示されます。
<html><head><title></title> <style>body { color: red !important }</style> </head><body>this is test <script> window.onload = function() { if (document.uniqueID) { document.body.runtimeStyle.color = "blue"; alert(document.body.currentStyle.color); // red } else { document.body.style.setProperty("color", "blue", "important"); } }; </script></body></html>
つまりどういうこと?
私は、!important よりも、runtimeStyle が優先されるものだと思っていましたが、それは思い込みだったようです。
- CSS に !important が書かれていると、JavaScript レベルでスタイルをオーバーライドできなくなる。
- CSSそのものに手を入れようとしても(CSSパーサーの日記参照)、document.styleSheets.rules にアクセスした瞬間、元の CSS は改悪され手出しできなくなる。
静的に指定された !important が、動的に指定された runtimeStyle よりも優先されるってのは、致命的です。js から何もできなくなってしまいますから。
本当に方法が無いの?
方法はあります。
スタイルシートを追加し !important なルールを後から追加するのです。これでルールを上書できます。
IE6, IE7 で以下のコードを実行すると、メッセージボックスが表示されている間は、緑の "this is test" が表示されます。
<html><head><title></title> <style>body { color: red !important }</style> </head><body>this is test <script> window.onload = function() { if (document.uniqueID) { document.body.runtimeStyle.color = "blue"; alert(document.body.currentStyle.color); // red var _sheet = document.createStyleSheet(); _sheet.addRule("body", "color:green !important; font-size: 20pt"); alert(document.body.currentStyle.color); // green _sheet.removeRule(_sheet.rules.length - 1); } else { document.body.style.setProperty("color", "blue", "important"); } }; </script></body></html>
IE8 は?
メッセージボックスを表示するタイミングによって、文字が赤いままだったりしますが、ルールを削除しない場合はちゃんと適用されているので、大丈夫のようです。
alert(document.body.currentStyle.color); // green // _sheet.removeRule(_sheet.rules.length - 1);
IE8は、モーダルダイアログを表示していても、裏が最新の状態に更新される訳では無いようなので、スクリーンショットを取る場合は気をつけたいですね。