IE6とIE7でCSSの:focus疑似クラスを使うには

Read More

IE6とIE7ではinput要素に:focus疑似クラスが使えない。


その代わりIEのbehavior(ビヘイビア)という機能を利用して動的に:focus疑似クラスを作成する方法がある。
# behaviorとはIE5からサポートされた機能で、DHMLやjavascriptを利用してHTMLの内容を動的に変更するというもの。

有名なものとしてはcsshover3.htcがある。
http://peterned.home.xs4all.nl/csshover.html


ただこれだとCSSファイルとは別にhtcファイルをアップしなくてはならなくなるし管理もメンドクサイ。


なんか別のアプローチは無いかな~とあれこれ見ていたら、

IEで:focus疑似クラスを適用するためのCSS:ずっと工事中
http://blog.livedoor.jp/eeu/archives/55131554.html

というページを見つけた。


ふむ、この人はexpressionsを利用しているようだ。


expressionsとはIEのCSSプロパティの拡張のために用意されたものだ。
ちなみにこの拡張機能はIE5から導入されたがIE8でそのサポートが終了している。

まあ流行らなかったということだな。


このやり方をすればCSSファイルとhtcファイルの2つも必要ない。
CSSファイル単体で:focus疑似クラスと同じことができる。

ただ純粋なCSSファイルという訳ではなく、
IEのCSSプロパティ拡張機能expressionsを利用してCSSファイル内にjavascriptを含めることになる。

これ自体は別に間違った使い方ではない。IEとして見た場合に限るが。



まずは基本となるサンプル。
■sample1.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<body>
<style type="text/css">
input:focus {
  background-color: #FFF1E1;
}
</style>
<input type="text" name="text" value="" />
<input type="submit" name="submit" value="submit" />
</body>
</html>



sample1.htmlはIE8、Firefoxでは期待した通りテキスト入力欄の背景色が変わる動作を見せる。
が、IE6、IE7ではまったく変化しない。



これをIE6、IE7でも動作させるには以下のように書く。
■sample2.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<body>
<style type="text/css">
input:focus, .input_focus {
  background-color: #FFF1E1;
}
*input {
  behavior: expression(
    (function(el) {
      if(typeof(behavior_onFocusIn) == 'undefined') {
        behavior_onFocusIn = function() {
          this.className += ' input_focus';
        };
        behavior_onFocusOut = function() {
          this.className = this.className.replace(/input_focus/, '');
        };
      }
      el.runtimeStyle.behavior = 'none';
      el.onfocusin = behavior_onFocusIn;
      el.onfocusout = behavior_onFocusOut;
    })(this)
  );
}
</style>
<input type="text" name="text" value="" />
<input type="submit" name="submit" value="submit" />
</body>
</html>



まずinput:focusの後ろにカンマ区切りで.input_focusというクラスを作っている。
この時クラス名のドットを忘れないように。


次にスターハックと呼ばれる方法を使ってIE6とIE7にのみに適用されるスタイルを書く。
先ほど作ったクラス名を2か所に適用する。
片方は前方に半角スペースが入っていることに注意。


これでIE6とIE7でも同じように:focus疑似クラスと同様の機能を実装することができる。



しかしこのままだとsubmitボタンにまで影響が出てしまう。



そこでtext型のinput要素にのみ適用させるためセレクタを使う。

ただセレクタを使うのなら注意点がいくつかある。
IE6ではセレクタがそもそも使えない。
IE7とIE8では標準モードでないとセレクタが正しく動作しない。

またIE6はCSSのある要素にセレクタを使ってしまうとその要素の同列に書いたクラスなどはまるごと無視される。
このためセレクタを使った要素と分けて書かなくてはならない。

んー、この辺はまた別の話だな。



まあそれらを踏まえると以下のようになる。

■sample3.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<body>
<style type="text/css">
input[type="text"]:focus {
  background-color: #FFF1E1;
}
.input_focus {
  background-color: #FFF1E1;
}
*input {
  behavior: expression(
    (function(el) {
      if(typeof(behavior_onFocusIn) == 'undefined') {
        behavior_onFocusIn = function() {
          if(this.type=='text') this.className += ' input_focus';
        };
        behavior_onFocusOut = function() {
          if(this.type=='text') this.className = this.className.replace(/input_focus/, '');
        };
      }
      el.runtimeStyle.behavior = 'none';
      el.onfocusin = behavior_onFocusIn;
      el.onfocusout = behavior_onFocusOut;
    })(this)
  );
}
</style>
<input type="text" name="text" value="" />
<input type="submit" name="submit" value="submit" />
</body>
</html>




ここまで書いて思ったが、
変化を付けたいHTMLのinput要素にちゃんとclass指定した方がもう少しキレイにかけたなあ。
textarea要素にも対応させるならなおさらだ。

そっちも書きたかったがスペースの関係上あきらめる。




まあIE6まできっちり対応させようと思ったらとんでもなく大変。


あと、bihavior使うにしろexpressionsを利用するにしろ、結局はjavascriptが有効であることが前提となる。


まあいまどきjavascript使わないサイトもないか。



その他の参考サイト)
■CSS Expressionsのサポート終了について
http://msdn.microsoft.com/ja-jp/ie/dd253083

■疑似クラスと疑似要素:CSS 前提知識
http://w3g.jp/css/guide/pseudo



Category "HTML・JS・CSS" の最新記事