HTMLとCSSはなんてクソなんだと、あなたに言わせるかもしれない理由。一般的にイライラさせられるHTMLとCSSの困惑、間違い、ジレンマの厳選した一覧。
Created by @mdo.
<input>
ボタン<button>
に type
を常に与える常に doctype を宣言しましょう。 私はシンプルな HTML5 doctype を推奨します。:
<!DOCTYPE html>
不正な形式のtable、inputなどと一緒にdoctype を抜かすことが問題を引き起こし、ページは互換モードでレンダリングされます。
width
が与えられている要素がpadding
かborder-width
を持ったとき、幅が広く
なります。この問題を避けるには、今では一般的なbox-sizing: border-box;
リセットを使用することです。
モバイルSafariが全てのプロパティの値でrem
の使用をサポートしていますが、メディアクエリのサイズ指定でrem
が使われたときに駄目になるようで、ページのテキストが違うサイズで無限に点滅します。
今のところ、rem
の代わりにem
を使いましょう。
html {
font-size: 16px;
}
/* モバイルSafariで点滅するバグを起こします */
@media (min-width: 40rem) {
html {
font-size: 20px;
}
}
/* モバイルSafariで問題なく機能します */
@media (min-width: 40em) {
html {
font-size: 20px;
}
}
助けが必要です! もし、これに関してAppleかWebkitのバグレポートへのリンクを知っていたら, それを追加できたらと思っています。私は、Safariのデスクトップではなくモバイルだけに対してこの報告がされているのがどこでなのか、明確に分かりません。
floatの要素はドキュメントの順番において常に最初にくるべきです。floatの要素は囲う何かを必要とします。そうしないと内容に次いで表示されるのではなく、下に入り込んでしまいます。
<div class="parent">
<div class="float">Float</div>
<div class="content">
<!-- ... -->
</div>
</div>
もしfloat
が使用されていれば、おそらくclearする必要があります。float
を使用した要素につづくどんな内容も、クリアされるまでその要素に巻きつきます。floatを解除するには、以下のいずれかのテクニックを使いましょう。
別クラスでfloatを解除するにはthe micro clearfixを使いましょう。
.clearfix:before,
.clearfix:after {
display: table;
content: "";
}
.clearfix:after {
clear: both;
}
あるいは、親要素でoverflow
をauto
かhidden
で使いましょう。
.parent {
overflow: auto; /* clearfix */
}
.other-parent {
overflow: hidden; /* clearfix */
}
一般的には親要素の中に配置された要素で、overflow
が意図しない副作用を引き起こすことに気をつけてください。
ヒント! 他の理由のために使用されることがあるので、floatを解除するとき`/ clearfix /`のようなコメントを入れておくことで、あなたと共同作業者の未来を幸せにしましょう。
floatを使用した中身だけを持つ親要素はheight: 0;
に計算されます。ブラウザに親要素の高さを算出させるにはclearfixを与えましょう。
float
を使った要素は自動的にdisplay: block;
になります。float
はdisplay
を上書きするし、必要もないので、両方を指定するのはやめましょう。
.element {
float: left;
display: block; /* 必要ない */
}
面白い事実: 数年前、マージンが倍になるバグをIE6で避けるために、適切にfloatを働かせるにはdisplay: inline;
を使う必要がありました。ですが、当時からずいぶん時間が経ちました。
隣接する要素(前後)のtopとbottomのマージンは様々な状況で崩壊しますが、決してfloatやabsoluteで配置した要素によるものではありません。詳しくは、MDNの記事を読むかCSS2の仕様のマージンの崩壊についてを参照してください。
水平方向に隣接したマージンは決して崩壊しません。
tableの行<tr>
は、親の<table>
に対してborder-collapse: collapse;
を与えない限りborder
を認識しません。さらに、<tr>
とその子の<td>
か<th>
が同じborder-width
を持っていれば、行にボーダーが適応されているのを見られません。例としてこのJSBinのリンクを見てください。
<input>
ボタン理由はよく分かりませんが、Firefoxは<input>
のsubmitとbuttonに対してユーザー定義のCSSで上書きできないline-height
を当てます。これに対処するのに2つの方法があります:
<button>
要素にするline-height
をボタンに使わない1つめの方法を取るのであれば(どっちみち<button>
は素晴らしいので私はこっちを推奨します)、知っておくべきことは以下のようなことです:
<!-- あまり良くありません -->
<input type="submit" value="Save changes">
<input type="button" value="Cancel">
<!-- いつでも最高です -->
<button type="submit">Save changes</button>
<button type="button">Cancel</button>
2つめの方法を取るのであれば、line-height
を与えないこととボタンのテキストを垂直方向に中央寄せするのにpadding
だけを使用することです。Firefoxで実際の問題と回避方法をこのJSBinの例で見てください。
グッドニュース! これについての修正がFirefox 30に含まれているようです。これは私たち自身の未来にとっていいニュースですが、古いバージョンでは修正されてないことに気をつけてください。
Firefoxは:focus
時のボタン(<input>
と<button>
)に内側のアウトラインを追加しました。明らかにアクセシビリティのためですが、その配置は奇妙に見えます。上書きするのにこのCSSを使ってください:
input::-moz-focus-inner,
button::-moz-focus-inner {
padding: 0;
border: 0;
}
この修正を、前のセクションでも紹介したのと同じJSBinの例で見ることができます。
ヒント! ボタン、リンク、inputに対してfocusの状態を持つようにさせましょう。タブを使うユーザーと視覚障害を持つユーザー両方にとって、アクセシビリティのためにアフォーダンスを提供することは最高のことです。
<button>
にtype
を常に与える初期値はsubmit
で、フォームの中のどのボタンもフォームを送信できてしまいます。フォームを送信しないボタン全てにtype="button"
を与えて、送信するボタンのみtype="submit"
を与えましょう。
<button type="submit">Save changes</button>
<button type="button">Cancel</button>
フォームの中にないけれどもアクションのために<button>
が必要なときは、type="button"
を使用しましょう。
<button class="dismiss" type="button">x</button>
面白い事実: 明らかにIE7は<button>
のvalue
属性を適切にサポートしていません。属性値を読み取る代わりに、innerHTML(<button>
の開始タグから終了タグの間の内容)から引っ張ってきています。ですが、2つの理由からあまり注目するべきことではないと思います: IE7の利用率は低下していってますし、<button>
にvalue
とinnerHTMLを両方与えることは、むしろ珍しいことなので。
IEの9とそれ以下のバージョンは、1つのスタイルシートで4,096のセレクタが上限になっています。また、1ページに対してスタイルシートと<style></style>
を合わせて31の上限もあります。このブラウザでは、この上限を超えたものは全て無視されます。CSSを分割するか、リファクタリングしましょう。私は後者を推奨します。
助けになる注釈として、どうやってブラウザがセレクタを数えるかを以下に示します:
/* 1つのセレクタ */
.element { }
/* 2つ以上のセレクタ */
.element,
.other-element { }
/* 3つ以上のセレクタ */
input[type="text"],
.form-control,
.form-group > input { }
position: fixed;
を使用した要素はブラウザのビューポートに相対して配置されます。position: absolute;
を使用した要素は、static
以外(relative
、absolute
、fixed
)で配置されている最も近い親要素に相対して配置されます。
position: [absolute|fixed];
とleft
とright
をもつ要素にwidth: 100%;
を与えないでください。width: 100%;
を使うことは、left: 0;
とright: 0;
を合わせて使うことと同じです。どちらか一方を使って、両方を使わないでください。
親要素がtransform
をもつとき、ブラウザはposition: fixed;
を壊します。transformを使うことによって、新しい包含ブロックを作成され、事実上親要素にposition: relative;
を持たせ、固定された要素がposition: absolute;
として振舞うようになります。
デモを見て、エリック・メイヤー氏によるこの問題についての投稿を読んでください。