スキップしてメイン コンテンツに移動

CSSだけでIEのjavascriptの有無を判定してスタイルを切り替える

追記

IE6でフリーズしました(>o<)。IE5.5とIE7・8(ie7モード)では動作。この辺りが目にしない理由でしょうか、、

追記2(05/02)

ActiveX の有効・無効と Javascript の有効・無効は個別に設定できますが、以下では js 無効なら ActiveX も無効だろう(その逆も)という前提で書かれています。いろいろ察してお読みください。

CSS だけで IE の javascript の有無を知りたい、というケースがごくごく僅かですがあるかな、ということでご紹介です。

IE の8までは透過やドロップシャドウ、グラデーションといった効果を独自拡張の filter プロパティで実現できて、他のモダンブラウザと近い表現ができます。

しかしこのプロパティは javascript が無効の場合は機能しません。(IETester では、javascript を無効にしても filter は機能するみたいです)

また、IE には CSS expression という独自拡張もあって CSS の未実装機能やバグの手当てに使われています。これも javascript が無効の場合は機能しません。(またIE8では同時期の他のブラウザに比べて CSS のサポート状況が貧弱にもかかわらず、標準準拠のIE8モードでは CSS expression が無効です。このおかげでIE5.5よりたちが悪いときもあります、、、)

そこで javascript が off のため filter が使えない、CSS expression が使えない場合に、スタイルを切り替えて対処する仕組みが必要になるかと思います。

スクリプトを使って(javascript が有効の場合は)、<body> タグのクラス名に ieJsEnabled を追加する、なんてことをすれば、そのクラスの有無でスタイルを切り替えることができます。

また javascript を使わないで HTML に以下のタグを書くことでも IE で js が無効の場合のスタイルを書くことができます。

<noscript><!--[if lt IE 9]><div id="ieJsDisabled"><![endif]--></noscript>

みんなが幸せになるなにか

<noscript><!--[if lt IE 9]></div><![endif]--></noscript>

で、何かの都合で以上なテクニックが使えない、使いたくない場合、CSS 内で js の判定を行う方法です。

CSS expression が動くということは javascript が有効なので、その CSS expression 内で自身の class 名を書き換えます。CSS expression はことあるごとにスクリプトの評価が起こってただでさえ遅い IE をますます不安定にしてしまうようですが、以下のような書き方の場合、最初の一回の評価以降はクラス名が書き換わって評価されないので大丈夫です。多分。また、同様にして id も書き換えられます。

.ieJsDisabled {
 scrollbar-shadow-color : expression(this.className='ieJsEnabled');
}

もっと汎用的にしたいと、this.className = this.className.replace(/ieJsDisabled/i, 'ieJsEnabled') としてみましたが動きませんでした。CSS expression 内では単純な代入しかできないみたいです。また this.style. ~な書き換えはできませんでした。

ついでに expression のダシに使うプロパティは、あまり影響の出なさそうなもの、ということで scrollbar-shadow-color にしてみました。

一年ほど前から HTML タグを発行するツールを制作して運用しています。当初は IE の javascript 無への配慮がなくて HTML も切り分けができるように書かれていませんでした。しかし今回の方法で、CSS を差し替えるだけで javascript 無にも対応できるようになりました。

以上はここ数日考えていて、昨日から検証して運用しています。もし導入される場合はぜひお手元で検証してから導入してください。