IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

Opera の CSSStyleSheet.insertRule はちょっとバグってる

以下のコード

var element = document.createElement('style');
element.appendChild(document.createTextNode(''));
document.getElementsByTagName('head')[0].appendChild(element);
var sheet = element.sheet;

// 以下のように CSSStyleSheet の先頭に二つのルールを挿入していく
sheet.insertRule('html body { background: gray }', 0); // 0 番目にこのルールを挿入
sheet.insertRule('html body { background: red }', 0);  // 0 番目にこのルールを挿入

このようにするとルールの順番は html body { background: gray } のほうが下にくるので、
カスケーディング順位(CSS のルールの優先順位)は html body{ background: red } より html body{ background: gray } のほうが上位になるはずである。
ということはこれを実行すると、body 要素の背景は gray になるはずである。

しかし Opera では

背景は red になってしまう。
これは、 OperainsertRule の第二引数に関わらず、ルールをルールリストの最後に挿入してしまうためである。

ブックマークレット化したので、実際にやってみてください。(IE は全くの独自仕様なのでこのブックマークレットはうごきません。あしからず)

javascript:var element=document.createElement('style');element.appendChild(document.createTextNode(''));document.getElementsByTagName('head')[0].appendChild(element);var sheet = element.sheet;sheet.insertRule('html body { background: gray }', 0);sheet.insertRule('html body { background: red }', 0);void(0);

まとめ

現状 insertRule を使う場合は、以下のようにルールをルールリストの最後に追加しなければブラウザ間の整合性が保てなくなってしまう。

sheet.insertRule('html body { background: black }', sheet.cssRules.length);

まあ、 IE 独自の addRule も最後にしか挿入できないし、どっちにしろそうなんだけどね(ぇ