IE6で複数クラスを使う時の注意点

カテゴリ:IEのCSSの問題を回避する技 2010年4月30日 10:00

複数クラスの使用

今さらですが、いちおう念のためってことで。
クラスは複数指定することができます。個別のクラスをひとつの要素に割り当てる、という使い方や、決まったクラスの組み合わせのみスタイルを適用する、なんていう使い方ができます。HTML、CSS の指定方法は以下の通りです。

HTML 側は上記のように、半角スペース区切りでクラスを指定すればそれで複数のクラスが指定されたことになります。(もちろん 2 つだけではなく、3 つ以上を指定することも可能です)

CSS 側は上記の 3 つ目の例のようにスペースを開けずにクラス名を連結させると、ふたつのクラスが指定されている要素にのみスタイルを割り当てることができます。(class1, class2 それぞれ別に定義している場合は、それらを合成したスタイルが割り当てられます)
これを適用すると以下のようになります。

複数クラスを指定し、上からclass1, class2, class1+class2のスタイルが当たった状態。

これを踏まえて。

複数クラスではまったのでメモ

ある案件で、複数クラスを使ったレイアウトをしていたら軽くはまったのでメモ的にエントリー。

IE6 で使う上での注意点

元々 IE6 では複数クラスの実装が不完全で、正確には理解していない、というのは知っていたんですが、まさか適用されない場合があるとは知りませんでした。

まず、複数クラスを使う場合の問題点。

IE6以下ではclassの複数指定は、CSS側のセレクタの記述は対応していないようで、並べられた最後のclass名単品でしか見られていないようです。

出典:IE6以下でclassの複数指定でバグがあった - Webコーダーの手帳

上記 引用はどういうことかというと、IE6 では CSS 側で複数のクラス指定に対応しておらず、いくら連結して指定したとしてもそれらがすべて無視され、最終的に最後に書かれたクラス名だけを読み取ってしまっている、ということです。イメージとしてはこんな感じ→.class1.class2.class3

そのため、以下のように CSS を指定しても、上記のサンプルの HTML にもスタイルが適用されてしまう、という問題が発生します。

▼実際に IE6 で表示してみた例

▼それ以外のブラウザ(キャプチャは Google Chrome)で表示した例

見てみると違いは明白ですね。本来、上記のように複数クラスを指定すると、class1, class2, class3 すべてが指定されている要素にのみ、スタイルが適用されるはずです。
しかし、IE6 では最後に書かれているclass2を読み取り、さも class2 として定義されたかのように 2 つ目と 3 つ目の要素にスタイルが適用されてしまっています。

なので、OOCSS の考えのような形で使用する分にはほとんど問題になりませんが、複数指定されている場合に表示を切り分ける、などのような使い方をする場合は注意が必要です。
下手をすると想定外の箇所にもスタイルが適用されて、レイアウトが崩れる、なんてこともあるかもしれません。

ID と連携して使用する場合の注意

さて、今回ハマったのがこちら。まず以下の引用を見てください。

1つのタグにidとclassを両方設定した際に起きるバグです。(わかりづらくて、すいません。。。)
このバグが発生する条件は少し限られていて、idで設定したスタイルをclassを付け替えることによって、見た目を変更しようとすると発生します。

ページのレイアウトは一緒だけど、色違いのページが数パターンあるという場合などで使用するかもしれませんね。

出典:IE6.0のバグ ?idとclassを両方設定した際

具体的にどういうことかというと、下記のコードを見てください。

まずは HTML から。
サンプルでは比較しやすいように id が重複していますが、通常のサイトのように 1 つであっても問題が発生します

続いて CSS。
#id.class と書くと、指定した id と class の両方が指定されている要素にのみスタイルを適用することができます。

想定としては、ID で大枠のレイアウトスタイルを書き、ページごと(あるいはモジュールごと)に class をつけかえて色や見た目を変化させる、という感じになるかと思います。(というかまさに今回ハマったのはそういった使い方でした)

上記のものを表示してみると以下のようになります。(Google Chrome でのキャプチャ)

見てみると、それぞれ上からしっかりとスタイルが適用されているのが分かるかと思います。
しかし、これを IE6 で見てみると下のような感じになります。

3 つの内、下ふたつにスタイル(背景色)が当たっていないのが分かると思います。
複数クラスの場合は、他で指定されたものが反映されていましたが、今回のサンプルでは完全にスタイルが無視されてしまっています。
こうなると、!important 規則を使ってもなにをしても反映されなくなってしまいます。(優先度ではなく、完全に無視されているような感じ)

バグの回避方法

そこで、このバグの回避方法が引用先の記事で書かれていました。そこで紹介されていたのは 2 つになります。

要素を追加して回避する

バグの発生条件にも書きましたが、どうやらセレクタの最後でクラスの付け替えによるスタイルの上書きをしようと試みた際に発生するようなので、最後に別のものを追加すれば回避することができます。

下記のソースでは、セレクタの最後をpにすることでバグを回避しています。

出典:IE6.0のバグ ?idとclassを両方設定した際

上記の説明を、今回のサンプルに適用すると以下のようになります。

このように、#id.class の指定をしている要素のさらに内側に、別の要素を追加します。(サンプルでは p 要素を追加していますが、p 以外でも大丈夫です)
そして CSS は以下のようにします。

こうすることで CSS の指定を認識してくれるようになります。(これが認識される、ということは id + class の指定はいちおう認識してるってことですよね・・なぜ最後に要素を足さないと認識しないのか・・まさにバグですね;)

ID と class を分ける

これは、#id.class という表記だとバグが発生するために、この連結での指定をやめてclass 単体でスタイルを指定する、というもの。
ただ、これだと根本の解決にはなっておらず、おそらく普通の指定方法となんら変わらないですよね。

それでもやはり、 IE6 対応を視野に入れるのであればこうした処置はやむを得ないことだとは思います。
また他のところでも言っていますが、ID でなければならない状況ってなにげに少ないと思っています。

JavaScript からアクセスする、というような用途がない限りは、class 指定だけでもスタイルを当てていくことはむずかしくありません。むしろ、ID の介入によって 優先度 が上がり、かなりしっかりと構造を定義しておかないと、後々別の箇所で新しい指定をしたい、と思ったときに上書きできずに、仕方なく id による優先度上げを行うしかない場合もあったりします。

そういう意味でも、あまり id での指定を多用せず、複数クラスの指定に留めておくのが安全かもしれません。

この記事のカテゴリー一覧を見る⇒IEのCSSの問題を回避する技

  • このエントリーをはてなブックマークに追加

トラックバックURL

http://css-eblog.com/cgi-bin/mt/mt-tb.cgi/178

トラックバック

SyntaxHighlighter3.0の落とし穴?IE6でハイライト機能が使えない件

WEBサイト上でソースコードを見やすく表示させるためのツール SyntaxHighlighter カスタマイズも自由自在! ヴぇのあもお気に入りの...

byHoLiC Full ThRottLe 2011年8月28日 07:22