構造のマークアップなしでフロートをクリアする方法

このページは、Position is Everthing(www.positioniseverything.net) で公開されているHow To Clear Floats Without Structural MarkupKuro が和訳したものです。このページの文書・画像・マルチメディアの著作権はすべて、元サイトにあります。翻訳は、Web翻訳等を利用しているため誤訳が多数見受けられますので、正確な和訳がございましたら原文をお読みいただくか、ご連絡ください。
このページは、元サイトと同じ描画を行うために、言語タイプ以外は同じコーディングとスタイルシートを使用しています。

(この新しいテクニックは元々 csscreator.com の Tony Aslett によって編み出されました。)

今まで使われていたフロートをクリアする道

float が見える border、背景を持ったコンテナボックスの中に含まれているとき、float より高くなってもその float は一番下の端まで自動的に押しやりません。 その代わりに、float はコンテナで無視され、旗のようにコンテナの下部から垂れ下がります。 Windows 版 Explorer だけに精通している人々は、頭をかきむしりながら「それは正しくない!」ということが正しいと言うかもしれません。Win/IE は「自動的に」コンテナの範囲内でフロートを囲みますが、しかしコンテナの要素が定まっている寸法を持つ場合だけで、それはいずれにせよ、W3C バリデーション違反です。 float していること、リンクの背景またはいくつかの他のプロパティを変更すると、このバリデーション違反である振る舞いはコンテナの範囲内でリンクすることによってオン・オフ'切り替えられる'ことができます。 めちゃくちゃです。

IEの熱狂的なブラウザ、Opera 7 はまた、それが問題なく無視されるかもしれないようにもし事実が以下の議論に何も多様にインパクトを与えなければ、コンテナが必要な大きさにされるフロートを囲みます。そしてくすくす笑っているにもかかわらず、励まされます。;-)

W3C はコンテナボックスで最後に"クリア"された要素を使用することを提案します。そして、それはコンテナによって認められます。そして、コンテナにクリアされた要素を囲むことを強制します。 「フロートの理論」の説明:

“..「さあボックスの下にクリアプロパティ  {clear: both;}  を与えてください。これがもたらすものはクリアするボックスの上にマージンを広げるということです。そして、それが下部のフロートをクリアするまで、それを押し下げます。 別の言葉(クリアするボックス(それがたとえ何にセットされたかもしれなくても)の上のトップマージン)で言い表すなら、長さがフロートの下部でクリアするとボックスを維持するのに必要であるものは何でも、ブラウザによって増やされます。”

それほど実質的に、そのようなクリアされたボックスが、前のフロートと同じ水平の面にあるはずがありません。 それは、水平の面の下にちょうど現れなければなりません。 このイメージでは、コンテナ要素を表現しているのは赤い境界線で、これがどのように見えるかについて示しています:

Shows how a box may clear below a float.

外のコンテナを入れ子にされたフロートを"囲む"ように見えさせるスタンダードな方法は、コンテナ内の最後に完全な"クリアされた"要素を置くことです。そして、それはフロートより低く含んでいる箱の下部の端を'引っ張る'影響をもたらします。 このように、たとえそれが本当でないとしても、フロートはコンテナの範囲内で囲まれるように見えます。 クリアされるボックスのためのコードは、通常このように見えます:

<div> <!-- float container -->
  <div style="float:left; width:30%;"><p>Some content</p></div>
  <p>Text not inside the float</p>
<div style="clear:both;"></div>
</div>

その div がフロートしないので、コンテナはそれを認めなければならなくて、それを囲まなければなりません、そして、その top margin("クリア"プロパティのため、ブラウザーによって加えられた)のため、div はフロートの一番下の端下でコンテナの一番下の端を"下げます"。

方法に関する問題

真っ先に言えるのは、このクリア方法はまったく直感的ではありません。そして、余分な要素がマークアップに加えられることを必要とします。 CSS の大前提のうちのひとつは、それらの膨らんだ HTML マークアップがこれらの日々において平均的なサイトに見つけてしまうのを減らす手助けになるということです。 マークアップをきちんとしたフロートを膨らまさなければならないことが維持できるように彼らのコンテナの範囲内で、理想的な取り決めはありません。

それの他に、若干のブラウザーは若干の状況で要素をクリアする特定の種類で苦労します。 Mozilla は、特に問題を解決することに敏感です。

こうする他のいかなる方法も現在までありませんでした、しかしもう不要なタグ必要ない! csscreator.comTony Aslett、作者とオペレータの努力のおかげで、われわれは現在非 IE ブラウザでフロートコンテナを「クリア」するために先進の CSS を使うことができ、ちょうど IE を誤ってそれ自体をクリアさせ続けることができます。 結果、我々には現在、その厄介な空の要素を HTML マークアップに加えることを避けるために任意の選択があるということです。 やったー!

"クリアすること"、21世紀のスタイル

新しい方法では、空要素は使われません。 これは単にいつものようにフロート(コンテナが定まった寸法を持つならば)を囲み続ける IE/Win に影響を及ぼしません。 しかし、非 IE ブラウザは代わりをその要素のために必要とします。 その方法が、ここにあります。

:after を使おう

CSS2 プロパティは、余分なコンテンツを CSS を通して要素の終わりに加えます。 それ(余分なコンテンツ)は、実際のマークアップ上の HTML 内で必要ないことを意味します。 ターゲット要素のすべての通常の内容の後で挿入された本物の HTML 要素がそうして、内容は CSS stylesheet 内から指定されて、ページに乗ります。 内容を含む :after は CSS プロパティ、'position' 'float'、list プロパティ、table プロパティを受け取れません。 しかしながら、'clear' プロパティだけは適用されます。 ここまではわかったかな?

私たちは period を使ってシンプルなキャラクタに :after を挿入します、それから  {clear: both;}  を発生する要素に与えます。 それはあなたが本当にやっつける必要があるすべてです、しかし誰も行間が彼らのクリーンなコンテナボックスの端を台無しにしていることを望みません、そこで私たちはまた {height:0;} と  {visibility: hidden;}  を使って表示される領域から我々の period で維持します。

.clearfix:after {
    content: "."; 
    display: block; 
    height: 0; 
    clear: both; 
    visibility: hidden;
}

 {display: block;}  の注意点として、また :after 要素にあてはまり、なぜならもしその要素のデフォルトの"inline" であると、"clear" プロパティを受け取れないからです。 また、Tony のオリジナルの理論では、ピリオドを隠すため "overflow:hidden;" を使っていましたが、残念なことにもしもこれを行ったとすると最新の Firefox では表示されてしまうでしょう。

でも IE についてはどうなの?

:after pseudoClass をサポートしない IE/Win 以来、私たちはその"自動クリア"効果に頼らなければなりません、しかし空き要素が寸法をそれに適用しておくとき、その振る舞いは起こるだけです。 多くの場合、高さか幅を指定することはしたくないです、しかし、幸いにもホーリーハックは我々を救います。 このハックは、IE/Win と IE/Win のみのコンテナについて単純な 1% の高さを参照させます。 それはどのように助けるのか? そう、IE/Win は偶然全てのボックスが、より小さいかもしれないどんなに定まった寸法でも問わず、すべての内容を拡大して、囲む原因となるもう一つの仕様違反があることが発生します! たとえどんな値がフロートを含むために必要でも1%の高さがちょうど拡大されるように、そして、寸法を適用する単なる事実は"自動フロートエンクローズ"の振る舞いを誘発します。 クールでしょ?

/* Hides from IE-mac \*/
* html .clearfix {height: 1%;}
/* End hide from IE-mac */

最初の行でちょうどコメントの終了タグの前にある"エスケープ"(赤で示された)でCSSのコメントになります。 そのエスケープがあるため、IE/mac は終了タグを無視してコメントアウトがまだ有効であると勘違いします。 このように、次に CSS コメントの終了タグがあるまで、すべてを無視します。 最後の行は通常のコメントです、そしてその終わりのタグは IE/Mac を再びコードを解析し始めさせます。

2行目は、ユニバーサルセレクタが"html"(また赤色)に続き 、ターゲット要素が続きます。 これはそれが HTML(本当の)の範囲内でネストである、そのうえ"html" がどんな要素の範囲内でもネストである .floatholder を選びます。 IEブラウザには"html"のまわりで見えなくて不可解なラッパー要素があるようにそれは起こるので、このセレクターは IE 以外では働きません。 それが IE/Win のようにボックスを大きくしないので、IE/Mac はこの高さを見るのを防がなければなりません、そしてこれはレイアウトに損害を与えます。

ひとつの利益を得ることで、この定まった寸法もいくつかのほかの大きくメジャーな IE/Win フロートバグを防ぎます。 しかしながら、このコンテナボックスは、ちゃんと、それのために前にある外部のフロート、IE の高さのバグ修正は Microsoft の 登録商標とフロートモデル違反を引き金にするでしょう、それを見届けなければなりませんか?

オンオフ切り替えるトラブル

IE には偶然にもこの自動 enclosing な振る舞いに関する小さな問題が幸運なこともあります。 あなたはそれを間近で見ましたね。はい、IE のバグは大きなふさで来ます。 そのコンテナ要素にリンクが入っているとき、これは起こります。そして、フロートに続きます。 これが発生するときに特定のリンク上に hover した際、オートenclosing の振る舞いは切り替えられ、"スイッチがオフ"になります。そのため、コンテナボックスの下部の端が浮いてしまいコンテンツの底が突然飛び上がってしまうのです。 その他のリンクを hover させると振る舞いが元に戻ります。 この面白いエフェクトは IE/Win ギロチンバグ と呼ばれていて、IE/Win で以下のライブデモを使って再現できるかもしれません、そして完璧な説明の続きを IE/Win ギロチンバグ デモページで見ることができます。

A:hoverリンクの背景か多くのほかのスタイルで変更する(例えばリンク上で変更する paddingmargin、またはいくつかのfont等)ことに慣れているとき、切り替わったときに起こるだけのようです。 不思議なことに、hover に関して text color を変更しても、バグへの切り替わりはありません

コンテナは緑色のボーダーで背景は灰色、そしてフロートは黄色のボーダーでダークブラウンです。 3番目と4番目のリンクに触れると Guillotine Bug に切り替わりフロート外側が動き、そして1番目と2番目に hover するとまた切り替わります。 これは彼自身実際のテキスト線に関連があるようなので、最初の2行のうしろのどんなリンクでもバグのエフェクトをオンオフ切り替わります。 フロートの中のリンクはすべてのエフェクトをオンオフで切り替えないでしょう。 ちょうどもっと怪しいIE バグの振る舞いは、人々は、"珍しく"ともなんともないです。
スクリーンショット

Float Link
フロートの外にある最初の2つのテキスト行リンクがそうなります、このフロートにあるどんなリンクでも領域の部分を元に戻します。何か、それらの最初の2行のラインが"特別に"見えます。
Link
Link
Link
Link
Float Link
左にあるフロートしていないリンクはパラグラフで包まれています、そして、そのパラグラフはホリーハックの値を適用しています。 ギロチンバグに「バイバイ」を言ってください!

Link
Link
Link
Link

2つ目ののデモは、パラグラフ内でそれらのリンクを置くことによって"修正"されました。そして、それから寸法をホーリーハックを使って適用させます。 どんなブロック要素でも、同じようにここで適用します。 はい、これはもう一つの要素が必要なことを意味します、しかし、空の div 要素と違って、このパラグラフは"意味のある"要素です。 テキストコンテンツはいずれにしろ意味のあるコンテナで本当は包まれるべきです、そして我々、将来を見通したコーディング技術者はこのように常に我々のコンテナを含んでおきます、同じく .clearfix クラスをもう一つの要素に適用するのは簡単になります。

フロート内のフロートの語句について

注意深い読者は、Opera7 と Mozilla でさえ上記のデモがフロートを"囲んだ"と気づきました! これはデモがフロートであるからです、そしてそれらの最新のブラウザは常にフロートを他のフロートに囲ませました。 IE もそうなります、そして実際それは誤って全ての要素(ちょうどフロートではない)を囲んでしまいます。 あまりにも間違った IE はホーリーハックなしではクリーンにすることができません。しかし、それはそこにあります。 少なくとも、それは修正することができます。そして、それは IE で必ずしも本当ではありません。 IE/Mac はフロートに関する独特の問題があるといわれています、そして Mac を持っている読者に完全にこの問題を外部でテストしてもらい、明白なレポートを提供してくれるなら、あなたを待ってからリンククレジットに置きたいです。

それらをまとめます

はじめに、このコードをスタイルシートに追加してください:

.clearfix:after {
    content: "."; 
    display: block; 
    height: 0; 
    clear: both; 
    visibility: hidden;
}

/* Hides from IE-mac \*/
* html .clearfix {height: 1%;}
/* End hide from IE-mac */

HTML で、ちょうど .clearfix のクラスをコンテナの範囲内のギロチンバグをフィックスしたい固定要素に追加して、クリアさせる必要があるフロートを含んでいるすべての要素に加えてください。 それがいい! それは完璧ではありません、しかし、それはすべての余分なダミーの要素を加えることよりかはベターでしょう。 アクション内にこのライブデモを位置から出してください:

このフロートは、周囲を div コンテナで囲まれていません。

このコンテナは、修正されていません。

コンテナで使用される余分な空 div なしで、このフロートがどのように含まれているボックスからも、もはや突き出ていないか見てください!

このフロートコンテナは、ブラウザに従い :after の修正が適用され、ホーリーハックを行った "clearfix" というクラスです。

IE/Mac の反撃

これはすばらしい、しかし残念なことに Mac の IE は"オートクリア"フロートを行わず、そのうえ :after をサポートしません、そして、クリアされたパーティの左外にいます。 何がされることになっていますか?

あなたは、無情にも IE/Mac を捨てるかもしれませんが、以前の Mac を使う多くの人々が Safari またはいくつかのモダンなブラウザを実行することができないことを考えるかもしれません。 ありがたいことに、このブラウザは Microsoft によって落とされました(注意:サポートがされなくなったこと)、そして、若干の時間とともに、そのような IE/Mac を使うユーザーの数は小さくなりつつあります。 例えフロートがコンテナから突き出ているように見えても、コンテンツが実は覆い隠されないことを思い出してください。 全てであるそれらの少ないビューワーのかわいく見えることで、それは見たくありません。 おのおのの著者は、彼らの特定のニーズによってこの問題を決めなければならないでしょう。

このページではかつて、IE/Mac で素直に強制するために Javascript による方法を述べました、しかし、現在は Mark HadleyMatt Keogh のおかげで、その醜い JavaScript を不要とし、真っ直ぐな CSS による修正に向かったため現在は対応可能です。 やったー!

IE/Mac フロート問題を抑える

基本的に、修正は .clearfix クラスの display: inline-table; を適用するための要素です、そしてその他全てのブラウザからプロパティを隠します。 それだ! 我々は、既存のコードで簡単に以下のようにします、そしてわずかに修正します。

.clearfix:after {
    content: "."; 
    display: block; 
    height: 0; 
    clear: both; 
    visibility: hidden;
}

.clearfix {display: inline-table;}

/* Hides from IE-mac \*/
* html .clearfix {height: 1%;}
.clearfix {display: block;}
/* End hide from IE-mac */

.clearfix の {display:inline-table;} は、すべてのブラウザで解釈され、IE/Mac は修正します。 それから、IE/Mac から隠されるルールセットの中で、display は block へリセットされます。 それは、彼女が書いたすべてです! 単に、上記のコードをあなたのCSS に差し込んで、かなり大きなフロートを含むどのようなボックスの親要素でも、.clearfix を使ってください。 それのほうがクールではないですか? 以前に言及されるので、ちょっと IEフロートモデルをオンオフする前の外部フロートに気をつけてください。

注意すべき言葉(これは重要です!)

W3C によるフロートの仕様によれば、クリアされた要素がすべての前にあるフロートの下に留まることを義務づけています。 この必要条件に対する例外がありません! このケースの"前"は、ソースドキュメントの最初に来るなんらかのフロートを意味します。

2004年11月に、Firefox は要素(全ての前のフロートよりむしろ)をクリアすることにより上に垂直にあったフロートだけをまだ間違ってクリアさせていました。 これはそれらの以前の Gecko ブラウザーで、あなたがスクリーンの一方の下にフロートするコラムを置くことができたことを意味しました、そしてもう1つのコラム(おそらく、もう一つはコラムをフロートさせた)の中に、前のフロートするコラムの下に落ちているそのクリアされた要素なしで、あなたはより小さなコンテンツのフロートをクリアさせることができました。 Gecko だけにこの問題があったので、これがページに起こるたびに何かが間違っていることは確かでした。 一般的に、Gecko はとても良いブラウザーです、しかし、この唯一のケースでは罪人同然でした。 よく考えてください、IE がいつも悪者ではないのです!

しかし、現在エクスプローラがまったく実際にはクリアされていない時から、全ての前にあるフロートをクリアさせるように Gecko ブラウザが最終的に修正される中、この簡単なクリア方法は、多くの問題を混乱させました。


...最悪だー! あなたにする何が現在我々の仮定的なフロートページであるかについてわかりますか? IE は、本当のクリア要素がわからず、とてもよいように見えます。 一方、より新しい Gecko と Opera7 ブラウザでは、その見えないクリアラーに垂直に前のフロートされたコラム(底があると仮定すること!)の底の下にいるまで、最初の簡単にクリアされた箱で要素を削除して発生する CSS は、ページの下にそのボックスの高さをドラッグします。 近くのフロートコラムの実際の高さに従い、これはその時だけ小さな簡易クリアボックスされたボックスの中に巨大な空のスペースを"生み出すことができます"。

もちろん、IE がする(バグを除いて)ように、オペラ7 は常に正しく空のスペースを実行し、Mac ブラウザはどちらも含まれません。 もしあなたがこの問題についてどのように解決されるかについて疑問を持っているなら、よくそうしません。 Gecko と Opera は両方とも正しい仕様でクリアさせています、そして IE は我々がそれに強制している見せかけられた"クリアする"ため、失敗するだけです。

外部へのクリアを防ぐこと

あなたは上記に記述した問題があるなら、隣接したフロートコラムをクリアさせることからより明白なものを防ぐ一つの方法は、コンテナ(クリアされたサイドのところ)でフロートすることです。 そのクリアラーがフロートするコンテナの範囲内であるなら、それはフロートされた容器の範囲内でそれを実行したフロートだけをクリアします。 クリアするための要素は、外部のフロートをクリアさせるために、そのフロートするコンテナの外に手を伸ばしません。 また、クリアのための要素はそのフロートの親にあたるコンテナ(それを少しの入れ子にした内部のフロートも含んだのは別)に、影響を及ぼしません。

オーケー、そこで構造上の変更を必要とするように、しかし、あなたより少ないものは考えるかもしれません。 実際、コラムをセットアップするすべての主な要素がフロートである場合、最悪 IE フロートバグは起こりません。 このように、コラム設計へのすべてフロートでやろうとするよりも、実は、少なくとも幅を固定したレイアウト内で、達成するほうがより簡単でしょう。

その他の IE/Mac とフロートに関すること

Alex Robinson によれば、inline-block を IE/Mac で幅が固定されていないフロートを幅いっぱいに拡大するのを防ぐために、フロートの中にブロック要素を使うことができるそうです。 それはフロートが幅を持たなければならなかったということです、しかし新しい仕様は幅が固定されていない"包装された"フロートを許します。 最新のブラウザの中の一つで、フロートが偶然1ブロック要素を含むことが起こるならば、IE/Mac は 100% までフロートを広げます。 さて、ちょっと上記の隠れている方法を用いて IE/Mac だけのためにその入れ子にされた要素を"inline-block"に切り替えてください、そしてフロートは IE/Mac では包装されるまでです。 2回フーを言います!! ちょうどネストしない中で更なる要素または彼らがそうするあらゆるブロック re-expand フロート、そして Philippe Wittenbergh が我々に警告するように、正常なフロートでこれを試さないでください。 Mac についての情報をありがとう、Philippe!

これらを手伝ってくれたみんなのために

我々に方法を見せてくれた、Tony Aslett感謝します。 彼のサイトである csscreator.com は、初心者と専門家が一緒に頭を抱えて、CSS のノウハウを意見交換するキラー CSS フォーラムです。 この方法のための Tony の元になったデモページはこちらで見つかります、そして、関連したフォーラムツリーはここにあります。

また、Firefox で"ピリオド問題"を指し示めしてくれたDoug、エレガントな IE/Mac のための Mark Hadley、すでに承認された CSS プロパティを使っている間 IE/Mac を修正するために "inline-table" を使う方法を示してくれた Matt Keogh へ栄誉を称します。 もう一度言わせていただくと、CSS コミュニティは我々のためにあります:-)


Holly 'n John   Holly へのお問い合わせ、John へのお問い合わせ ©positioniseverything
最終更新日: 2005年1月14日
作成日:2004年5月14日