IE6対策と、id, classの複数指定
IE6対策に必要な知識を整理するために、class、idの複数指定に関する実験をしてみました。
文字色、背景色、罫線色が、赤、緑、青となるように
.color_red {
color:#f00;
}
.color_green {
color:#090;
}
.color_blue {
color:#00f;
}
.bg_red {
background:#f99;
}
.bg_green {
background:#9f9;
}
.bg_blue {
background:#99f;
}
.border_red {
border:5px #f00 solid;
}
.border_green {
border:5px #0f0 solid;
}
.border_blue {
border:5px #00f solid;
}
#color_red {
color:#f00;
}
#color_green {
color:#090;
}
#color_blue {
color:#00f;
}
#bg_red {
background:#f99;
}
#bg_green {
background:#9f9;
}
#bg_blue {
background:#99f;
}
#border_red {
border:5px #f00 solid;
}
#border_green {
border:5px #0f0 solid;
}
#border_blue {
border:5px #00f solid;
}
として、
htmlに複数classを指定
してみると、
赤文字 青背景 青罫線
青文字 赤背景 赤罫線
結果↓
赤文字 青背景 青罫線
青文字 赤背景 赤罫線
htmlに複数idを指定
すると
idは1つだけなら指定できるけど
2つ以上は指定できない
結果↓
idは1つだけなら指定できるけど
2つ以上は指定できない
となることから、
- 1つの要素に複数classを指定したい場合は、class名を半角スペースで区切る
- 1つの要素に複数idを指定することはできない
ということが分かります。これはIE6, IE7, IE8, Firefox, Opera, Google Chrome, Safariで正しく見えました。…………(*)
で、これはhtml側での複数指定ですが、次に
css側での複数指定
について見るために、
.color_red.bg_blue.border_green {
font-size:80px;
}
とすると、
.color_red.bg_blue.border_greenに80px
とした場合に限って、
.color_red.bg_blue.border_greenに80px
となることから、これはclassが「color_red」かつ「bg_red」かつ「border_green」の場合、font-sizeに80pxを与える指定ということが分かります。
以下、いろいろな組み合わせを試そうとすると前に書いた記述に影響するのでやらずに結論だけ書きますが、ぱっと見似ている
.color_red,.bg_blue,.border_green {
font-size:80px;
}
はclassが「color_red」と「bg_red」と「border_green」のものは、font-sizeに80pxを与えるという記述なので、こう(↓)まとめると分かりやすいと思います。
- cssにピリオド(.)+class名を続けて記述した場合は「and」条件
- cssにピリオド(.)+class名をカンマ(,)で区切って記述した場合は「and」条件
「おれ~、おかしいなぁ」と思ってCSSを細かく見ていたら、カンマが抜けていたとか入っていたとか、そんなことがよくあります。
(これはidとの組み合わせでも成り立ちますが、後述します)
が、
やっかいなのは、(*)以降は、IE6を除く話だということ。
例えば
緑文字 緑背景 緑罫線
は、今までの指定だと正しくは文字サイズは小さいままですが、IE6だけ、文字が大きくなっているはずです。
結果↓
緑文字 緑背景 緑罫線
これは、
IE6ではCSSの複数class指定は実装しておらず、並べられたクラスの最後のもののみ適用される
というもので、上の例では、「color_green」があろうがなかろうが、「bg_green」があろうがなかろうが、最後の「border_green」さえあればフォントサイズを80pxにすると解釈されてしまうんです
で、保留していたidとclassの複合指定ですが、
#color_red.bg_red.border_red {
font-size:80px;
}
#color_red.bg_blue.border_red {
font-size:80px;
}
#color_red.bg_green.border_red {
font-size:80px;
}
としたとき、本当は同一ページに同じidのものを2つ以上書くのは反則ですが、別々に試しても下のように書いても結果は同じだったので、説明の都合上この(↓)ように書きますが、
の結果は、赤文字 赤背景 赤罫線
赤文字 青背景 赤罫線
赤文字 緑背景 赤罫線
赤文字 黒背景 赤罫線
赤文字 赤背景 赤罫線
赤文字 青背景 赤罫線
赤文字 緑背景 赤罫線
赤文字 黒背景 赤罫線
となり、idと複数class指定の組み合わせも成り立つということが分かります。
最後の「bg_black」は今回定義していないので、当然80pxにはならないし、黒背景にもなりませんが、IE6は、前述したとおり「classの複数指定は最後のclassを解釈する」という規則通り、文字が大きくなりました(背景色はさすがに黒にはならない)。
ただし、この書き方は、IE6で複数クラスを使う時の注意点 | CSS-EBLOGの「IDと連携して使用する場合の注意」からすればうまくいかないはずですが、うまくいっちゃいました。
確かに、idとclassの複合で、思い通りにならないことは良くあるので、そういうバグはあるとは思うのですが、いまひとつ、どのような条件のときに起きるのか、まだ分かりません。
分かったらまた追記したいと思います。
マージンの話
(注)検証はIE6, IE7, IE8, Firefox, Opera, Google Chrome, Safari にて行いました。IE以外はヴァージョンの違いは気にしなくても良い内容だと思います。
<html>, <body>, <p> のデフォルトのマージンがどうなっているか調べるために、
css↓
html {
background:#000;
}
body {
background:#fff;
}
p {
background:#f00;
}
p span {
background:#0ff;
}
html↓
<html> <body> <p>背景が黒いのはhtml</p> <p>背景が白いのはbody</p> <p>背景が赤いのはp</p> <p>背景が青いのは<span>pの中のspan</span></p> </body> </html>
としたとき、各ブラウザでの表示は以下のようになりました。
(図1)
(↑IE6での表示。他もだいたいこんな感じ)
これは、cssの1行目に「すべてのpaddingを0にする」という
* {
padding:0;
}
を加えても変わらなかったので、余白はmarginによるものだと分かります。
ただし、FirefoxとSafariにおいては、<p>の内部にわずかな隙間ができているように見えます。


<p>のpaddingを0にしたはずなのに、おかしいなぁ、と思いましたが、しばらくして原因は別のところにあることが分かりました。「line-height」の値を変えたら表示が変化したのです。なるほど。「font-size」や「line-hight」のデフォルト値についての比較はここでは省略します。
ということで備忘録その1として
- <body>には上下左右に10px程度の余白ができる(その値はブラウザに依存)
- <p>には上下に1emの余白ができる(ただし詳細説明が必要なので下記参照)
<p>の余白に関してですが、IE6とIE7では違うようです。おそらくバグです。おそらくIEのバグです。おそらくIFE(Internet Fuckin’ Explorer)のバグです。IEのバグです。大切なことなので4回書きました。font-sizeを色々変えても、IE6とIE7だけ間隔が変わらないのです。1em自体の長さ(1文字文の長さ)はIE6でもIE7でも正しく解釈するのですが、<p>の上下の余白はおそらくデフォルトのfont-sizeの1emを取っているのではないかと思われます。
ところで、上の表示結果をみれば「あれ?」と思うかもしれません。上下に1emの余白ではなく、上か下かに1em、あるいは上下に0.5emではないかと。そして、一番上と一番下が変です。でも、
p {
margin:1em 0;
}
とやっても同じ結果でしたので、確かに上下に1emのマージンをとっています。
それについては「default <p> margins」にはこうあります。
> Without css a <p> gets a blank line before and after > 1) even when there is an image > 2) except when the <p> is on top. > But when changing the margins with css, these two behaviours are gone. > Is there a workaround for this? The reason (1) and (2) happen is because, with most browsers, there’s a default style rule that behaves like this: p { margin: 1em 0; } So <p> will always have a single line-height margin on top and on bottom, regardless of contents (images, texts, input elements, whatever). If "the <p> is on top", I’m not sure exactly what you mean by this. On top of what? My best guess is that you mean on top of another <p>. In this case, the vertical margins collapse, which means that the space between the two <p> tags (or any other elements with vertical margins) will be the greater of the two margins, not the sum of the two margins. For two unstyled <p> tags, that means there will only be 1em of space between them, not 2em (as it would be if you added the margins).
質問者の「except when the <p> is on top.(<p>が一番上にあるときは例外)」に対して回答者は「On top of what?(何の一番上?)」と尋ねていますが、「同一ボックス内の一番上」という意味だと思います。実際、(図1)では一番上と一番下が例外のようになっています。
これについては、
body {
background:#fff;
border:1px solid #00f; /* ←追加 */
}
と、<body>にborder(ここでは幅1pxの青直線)を引くと

一番上の上側と、一番下の下側に余白が出ました。ただしIE6, IE7は違ってこんな感じ。
↓

これについては、現象を一般化してそれを覚えるのは脳味噌のシワの無駄使いのような気がするので、不具合が出たらその都度対処した方が良いような気がします。
それよりも興味深いのは、「the vertical margins collapse, which means that the space between the two <p> tags (or any other elements with vertical margins) will be the greater of the two margins, not the sum of the two margins.」(<p>タグ(あるいは上下にマージンを持つ他の要素)間のスペースは、大きいほうのマージンを取り、和にはならない)と言われている点です。
「marginとは – はてなキーワード」にも、注意に書いてありますが、
上下方向にmarginを持つものが隣接する場合、マージンの相殺がある
ようです。ただし、
隣接するマージン値が同符号の場合は絶対値の大きい方をとり、異符号の場合は和になる
という具合に。これは、実際に試してみると<p>でも<div>でも<h1>~<h6>でも同じでした。
(例)
css
↓
div {
background:#fee;
border:1px #000 solid;
}
p.m1 {
background:#200;
color:#fff;
margin:100px 0 20px;
}
p.m2 {
background:#800;
color:#fff;
margin:100px 40px -20px;
}
p.m3 {
background:#880;
color:#fff;
margin:100px 80px -20px;
}
p.m4 {
background:#080;
color:#fff;
margin:-50px 120px 100px;
}
html
↓
<div> <p class="m1">(1)余白:上100px 下 20px</p> <p class="m2">(2)余白:上100px 下-20px</p> <p class="m3">(3)余白:上100px 下-20px</p> <p class="m4">(4)余白:上-50px 下100px</p> </div>
結果
↓
(1)余白:上100px 下 20px
(2)余白:上100px 下-20px
(3)余白:上100px 下-20px
(4)余白:上-50px 下100px
IE8, Firefox, Opera, Google Chrome, Safari で、こんな感じに表示されています。

ただし、この場合もIE6とIE7は表示が崩れました。marginにマイナス値を与えたのが原因でしょう。でもそんなケースは少ないし、ハックするのが面倒なので、代わりにここにその醜態を晒しておきます。
IE6
IE7


