カテゴリー:IEのCSSの問題を回避する技

リスト表示へ

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

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 での指定を多用せず、複数クラスの指定に留めておくのが安全かもしれません。

RGBaを使ったプログレッシブ・エンハンスメントと注意点

2010年1月27日 14:16

いきなりはてブで vantguarde さんに突っ込まれました・・。今回の件はプログレッシブ・エンハンスメントではないですね。フォールバック、というらしいです。
プログレッシブ・エンハンスメントは、「なくても内容が破綻しない」というときのことですね。今回は "代替" を用意してるので違う、と。てか、こうなるとすでにタイトルが破綻してる気が・・w とりあえず積極的に新しい技術を使っていこう、という気持ちは変わらないので、このままにしておきます、ってことでいちおう注意。
ちなみに CSSのプログレッシブエンハンスメントの例 にちょっと詳しく書いてありました。

ちょっと面白い記事を見つけたので紹介です。(元記事: IE Background RGB Bug

概要はというと、単一セレクタによる指定で RGBa に対応していない IE6, 7 に対処しつつ、対応しているブラウザには RGBa を適用させる、というときの注意点です。

RGBa を使う

RGBa は、IE6, 7 は対応していません。なので、もしそのまま指定すると当然、IE6, 7 では背景色がない状態になってしまいます。
背景色がなくても問題ないこともありますが、例えばベースのテキストカラーが白(黒背景)で、見出しだけ白っぽい背景にした、などという場合、当然その見出しに載せるテキストカラーは黒に近い色になると思います。

そんなとき、もし背景色が表示されないとなるとテキストが見づらいばかりか、最悪の場合見れない、などということにもなりかねませんよね。
なので、RGBa に対応していない IE6, 7 であっても適切に文字が見えるようにしなければなりません。

CSS ハックを利用して、IE6, 7 だけに改めて背景の色を指定する、ということも考えられますがやや冗長になってしまいます。そこで、ひとつのセレクタ内で完結する記述方法が下記です。

CSS ソース01

こうして並べて記述することで、IE6, 7 とモダンブラウザ双方とも背景色が表示されるようになります。

注意点

しかし、元記事でも触れていますが、この方法、ショートハンド(backgroundのみのもの)で指定しないと IE6, 7 では反映しないようです。なので、下記のように書いてしまうと IE6, 7 では背景色が表示されません。

CSS ソース02

プログレッシブ・エンハンスメントという考え方

最近では、モダンブラウザで使える機能は積極的に使い、IE6(場合によっては IE7)などの対応していないブラウザに対しては同じような表示になるよ代替を用意する、という "プログレッシブ・エンハンスメント" という考え方が徐々に広まってきています。
RGBa はとても使いやすい機能なので、積極的に使っていきたいですね。

ちなみに、IE6, 7 では RGBa に対応していない、と書きましたが、filter をうまく使うと RGBa のようなことを実現することは可能です。以前、IE6, IE7でもRGBaを使う という記事を書いたので、よかったら参考にしてみてください。

IE6, IE7でもRGBaを使う

2009年12月 9日 23:52

正確には RGBa っぽく表示させる、ですがw
IE6, IE7 は RGBa に対応していません。

ですが、IE の独自拡張である filter を使うと RGBa と同じことが実現可能です。
ただ注意点として、JavaScript オフで見ているユーザの場合は処理されなくなってしまうので、JS で制御するような LightBox などで表示したポップアップに対して使用しておくと問題なく使えると思います。

HTML ソース

CSS ソース

簡単に説明すると、filter のグラデーション機能の透明度を利用します。
上記サンプルの filter は本来グラデーションを指定するものなのですが、グラデーションの色にアルファ値を持った値を設定できるのです。

サンプルで言うと、#B4000000の部分ですね。数値は 16 新数の 8 桁で指定し、最初の 2 桁が透明度を表します。00 で透明、FF で不透明となります。

つまり、始まりと終わりの色と透明度を同じにしてしまえば、まるで RGBa のような振る舞いになる、というわけです。
ただ、filter は CPU に負荷をかけるので、あまり多用しないほうがいいかもしれません。
上でも書いたように、ちょっとしたポップアップなどに利用する程度にしておくといいと思います。

それから 1 点問題として、IE7 では filter を使った場合、clearType のフォント(メイリオとか)が細くなる(アンチエイリアスがなくなる)という問題があります。
そのあたりも考慮した上で使用してみてください。

IE6でもCSSのみでmax-widthを実現する

2009年11月11日 00:55

IE6でもCSSのみでmax-widthを実現している図

今回も CSS Play でのテクニックの紹介です。
タイトル通り、IE6 には対応していないはずのmax-widthをハックなしの CSS のみで実現する方法が書かれています。n

ただ、多少 HTML を工夫しないといけない箇所があり、まったくの CSS のみ、とは違うかもしれませんが、div 要素を 2 個ほど追加するだけなので、それでデザインの制限がはずれるなら積極的に採用してもいいと思います。n

こちらの件はコリスさんの [CSS]ハック無しでIE6でmax-widthを実現するスタイルシート でも紹介されていました。n

さて、今回もこのテクニックをひも解いていってみましょう。このテクニックの肝は、overflow: hiddenの意外な使い方にあります。(結構当たり前? でも自分は結構最近知りました・・)n

実際の demo は以下にあります。それぞれ、コンテンツをセンタリングさせたもの、左寄せ、右寄せとなっています。n

IE6,7で、疑似要素を指定した要素に隣接するスタイルがおかしくなる件

2009年5月 8日 14:00

Yahoo!知恵袋を覘いていて、ちょっと興味深いものを発見したのでエントリー。n

概要を書くと、":first-letterなどの疑似要素を指定した要素に隣接する要素のスタイルが崩れる" というもの。(タイトルまんまですね)n

まずは以下のサンプルを、IE6,7 で見てみてください。n

見ていただくと分かりますが、2 つ目以降のテキストが、ボックスからはみ出しているのが分かると思います。
ボックスがずれているならまだしも、はみ出すのは完全にバグですよね。n

サンプル 01 がなんの対策もしていないもの、サンプル 02 が対策をしたものになります。n

これは推測ですが、おそらく IE の場合、疑似要素を適用すると hasLayout が false にでもなるのではないでしょうか。そのために、隣接する要素のスタイルに影響が及ぶと。n

試しに、隣接させないよう <br /> など別の要素を入れるとテキストはボックスからはみ出さずに正常に表示されるようになります。n

hasLayout ではないか、と思った要因は、hasLayout を ture にするプロパティを指定すると(サンプルでは zoom: 1;)この問題が改善されるためです。n

今回のサンプルでは:first-letterでしたが、:first-lineでも同様の現象が発生しました。そのため、問題は "疑似要素ではないか" と思ったわけです。n

とりあえず、疑似要素を指定した要素の前後で問題が発生した場合はzoom: 1;を追加することで問題は回避できそうです。n

CSS ソース

HTML ソース

CSSのみでIE6にposition:fixedを対応させる

2009年3月16日 13:09

[2009/08/14 修正]
内容が若干分かりづらかったので加筆しました。全体的な内容は変わっていません。
[2009/03/22 修正]
サンプルの問題の修正に合わせて、記事を書き直しました。

今回は IE6 でも、CSS だけでposition: fixedを実現するテクニックです。
通常、IE6 ではposition: fixedをサポートしていないため、普通に指定するだけでは固定配置されません。

今回紹介するテクニックは、いくつかの IE6 のレンダリングの誤差を使って巧みに position: fixed を実現する方法です。
まずは以下のデモを IE6 で見てみてください。ちゃんと右下に固定配置されているのが分かると思います。

IE6 に position: fixed を適用させるデモ

大きく分けると、実現するための方法としての要点は 5 つ。

  1. 標準準拠モードで動作するよう、DOCTYPE 宣言を記述する。
  2. html, body 共に height: 100% を指定する。
  3. スクロール対策として、全体をくくる div 要素を追加する。
  4. 固定配置したい要素に対して position: absolute を指定する。
  5. 固定配置したい要素を、全体をくくっている div の外に配置する。

上記 5 点を踏まえて HTML、CSS を書くと以下のようになります。

IE6で透過PNGを手軽に使えるJavascriptライブラリ「DD_belatedPNG」

2009年2月12日 23:47

site_DD_belatedPNG.jpg

今回はサイト製作に便利な JavaScript ライブラリの紹介です。

DD_belatedPNG

IE6 では透過 PNG(PNG-24 PNG-32 の間違いでした;)を使えません。
いちおう画像を表示することはできますが、透過部分が反映されません。

しかし、代替処理として「AlphaImageLoader」という CSS の filter を使うことで使うことが可能です。
ですがこれ、ActiveXの問題なのか、指定している透過PNG画像のドメインが違うとうまく反映されませんでした。

しかし今回紹介するJavascriptライブラリは、VMLという技術を使ってPNG画像の透過を実現します。

そのため、ドメインなどの問題もなく、しかも指定も楽でimg要素、CSSともに使用できるためとても便利です。

しかしながら、やはりこちらも使用には何点か注意点があります。
CSSの背景にPNG画像を指定した場合は問題ありませんが、img要素に(つまり通常の画像として)指定した場合、いくつかのライブラリで実装する、フェードアウトやフェードインの視覚的効果が実行されません。

推測では、filter 機能が使えないために透明度が変更できないのだと思います。
なので、もしこのライブラリを使う場合は CSS の背景として使うのが無難です。
簡単にデモを作ってみたので見てみてください。

使い方

スクリプトファイルを読み込んだあと、「DD_belatedPNG.fix('.png_bg');」で透過 PNG を使用している要素を指定します。
指定の仕方は簡単で、CSS セレクタと同じように指定ができます。
複数指定する場合は、やはり CSS と同じようにカンマ区切りで列挙します。

合わせて読むと役に立つかもなエントリー

IE6で背景が表示されない際にチェックすること

2009年2月 4日 23:44

さて、今回はやや趣向を変えて IE6 に絞って話をしたいと思います。
先日、久々に IE6 で自分のブログを見たらなんだか微妙に変な感じに。n

よく見てみたら、各タイトル部分の背景が所々表示されていませんでした。
この「背景が表示されない」というバグ、IE6 では時折見かけます。
以前書いた peek-a-booバグ というのもそのひとつ。n

今まで自分が経験した中で、この背景が表示されない現象を回避したものをいくつか書いてみようと思います。n

clearfix を使う

これは IE6 だけに限った話ではありませんが、float を使用してレイアウトをしていると遭遇する問題です。
子要素がすべて float していると親要素は正常に高さを判別できません。そのため、まるで背景が消失したかのように見えてしまいます。
これの解決には clearfix というハックを用いて対処します。n

なぜ clearfix を使うと背景が表示されるのかについては、初心者が陥りそうなCSSの7の間違い で詳しく説明しています。n

背景が表示されない要素に「zoom: 1;」を指定

zoom は、IE の独自プロパティであり、さらに IE に実装されている hasLayout の値を true にしてくれるプロパティです。
この hasLayout 、該当要素がレイアウト(ボックスモデル?)を持っているかどうか、を判定するもので、これが true になると高さや幅、marginなどの値が適用されるようになります。n

なので、CSSの解釈でFirefoxなどのモダンブラウザと比べてなんか違うな、と思ったらとりあえず指定してみると色々解決するかもしれません。n

背景が表示されない要素に「position: relative;」を指定

IE6の場合、ネガティブマージン(マイナス値の margin)を使うと時々変な挙動をすることがあります。
そのひとつとして背景が表示されない、というものがあります。
これ、まさに自分のブログで起きた現象でした;n

しかも、すべて同じ class の要素なのにもかかわらず、背景が表示されるものと表示されないものがあるのが厄介でした。
よくよく見てみたら、margin-left にマイナスの値を設定していたので、もしや、と思って position: relative を指定してみたところ、正常に背景が表示されました。n

また、これとは別にネガティブマージンを指定した要素内に画像がある場合、本来表示されるべき場所からマイナス方向に移動した分が切れる(本来表示されるべき場所でマスクされた感じ)という現象があります。n

これも同様にして、画像の親要素に対して position: relative を指定することで正常に表示されるようになります。n

2行追加するだけで、簡単にIE6でもmin-heightを実現する方法

2008年3月27日 15:11

CREAMU さんのところで書かれていたCSSでmin-heightをクロスブラウザにする最も簡単な方法『Easiest cross-browser CSS min-height』を参考に、サンプルを作ってみました。

自分でも覚えておきたいので備忘録的にもエントリーw
ちょっと前に書いた『CSSの1行でできるIE6対策(ハック)』と同じテクニックを使ったものです。
IE6 で下のサンプルを見てもらうとわかると思いますが、見事にmin-heightと同じ挙動をしています。

2行追加するだけで、簡単にIE6でもmin-heightを実現する方法デモ

解説は以下から。

IEのCSSの不具合を直す魔法の言葉「zoom:1」

2007年5月17日 17:50

今回もまた備忘録的なものです。n

IE の CSS 表示で、たまになんだか変な挙動になることありませんか?
高さがおかしくなったり、場所がずれたり。
ちょっとどこで読んだか忘れてしまったんですが、どうやら特定のスタイルを適用すると、レンダリングが変わるんだかなんだかだとか。
hasLayoutONになるプロパティを指定すると、CSS の解釈が変わります。(IE のみ)

なので、たまにheightborderを設定すると表示が改善された、なんてことありませんか?
それらが、その「特定のスタイル」のようです。
だから、それらを設定することで正常に表示されたりするんですね。n

ただ、borderにしろheightにしろ、IE 用に適用させてしまうと、他のブラウザ(Firefox とか)に影響が出ちゃいますよね。n

そんなときにzoom:1です。
これは IE 独自スタイルにも関わらず、上で書いたように「特定のスタイル」の中に含まれます。
なので、heightなどで表示が改善されるような場合、そのスタイルにzoom:1を指定しておけば他のブラウザに影響を与えることなく IE だけにスタイルを適用することが可能となります。n

なんかで行き詰ったら試してみるといいかも?n

1  2