2012-02-01

clearfix のアレンジ版作ってみました

Firefox 3.6 が clearfix の影響で margin-bottom が margin-top にもかかるという話を聞いて、普段使ってた clearfix で試してみたところ、同様の現象が出たので、対応版を作ってみました。

追記(2012年2月7日): 公開当初のコードでは問題があったので、最後に追記しました。

ネタ元の記事は以下。
firefoxでmargin-bottomがmargin-top | 乱雑モックアップ

この記事で紹介されていた clearfix は以下ようなもの。
僕はこの指定から height:0; を抜いたものを使っていました。

.clearfix:after{
  content: '';
  display: block;
  clear: both;
  height: 0;
}
.clearfix{
  /zoom: 1;
}

そして、解決方法として教えてもらったのが hail2u.net さんのデモ。
firefoxでmargin-bottomがmargin-topになったりするのを回避する

この解決方法は、height:0;height:0.01px; にしています。

.clearfix:after{
  content: '';
  display: block;
  clear: both;
  height: 0.01px;
}
.clearfix{
  /zoom: 1;
}

この記事の公開時点(2012年2月1日)の最新版 Firefox 10.0 でも 3.6 と同様の挙動で、hail2u.net さんの方法で解決できます

アレンジ版作ってみました

height:0.01px; の指定で解決できますが、他の解決方法がないかと試してみました。
なお、zoom:1; の部分は共通なので、以下のコードでは省略しています。

検証ブラウザは以下の通り。
※ Mac: Mac OS X Lion、Win: Windows 7

Internet Explorer 6、7 は関係しない変更なので、検証はしていません。
また、検証したのは Firefox の4つのバージョンのみで、バージョン 5 〜 8 では未検証です。
リリース直前だったので、バージョン 9.0.1 と 10.0 で検証していますが、これに深い意味はないです。

元記事コメント欄版

元記事で、.clearfix:afteroverflow:hidden; を指定すれば、height:0; の指定は必要なくなるとのコメントが書かれていたので試してみたところ、問題なく動作しました。
また、overflow:auto; を指定してもうまくいきました。

.clearfix:after{
  content: "";
  display: block;
  clear: both;
  overflow: hidden;
}

この2つは、「clearfix を使わずに float を解除する」みたいなやつと同じってことですかねってことで、深く追ってません。

height:0; を別のプロパティに変えてみた版

clearfix のバリエーションのうち、.clearfix 側に min-height:1%; って使ってたなーと思って試したらうまくいっちゃった版。

.clearfix:after{
  content: "";
  display: block;
  clear: both;
  min-height: 1%;
}

visibility:hidden; など他のプロパティも試してみましたが、うまくいかず。
複数のプロパティの組み合わせでうまくコントロールできるかもしれませんが、コードがどんどん長くなりそうだったので、このパターンはここまで。

display:block; を違うものにしてみた版

元記事で .clearfix 側に display:inline-block; を指定すると直ると書かれていました。
確かに変なマージンは取れましたが、これはこれで違う余白の問題が出る可能性高いので、あまり使いたくないかなと。
ということで、1つ前のパターン同様、.clearfix:after のほうに指定してみたところ、期待通りの動作になりました。

.clearfix:after{
  content: "";
  display: inline-block;
  clear: both;
}

また、display:table; or display:inline-table; でもうまくいきました。
display:table; のほうは、A new micro clearfix hack – Nicolas Gallagher と同じような感じになりました。
display:inline-table; はなんとなくやってみたら効いてくれた程度のものです。

まとめ

行数(覚える量)が増えずに意図した挙動をしてくれるということで、display:inline-block; を指定する版をしばらく使ってみようかなと思います。
一番コード量が少ないのは display:table; ですが、なんとなく気持ち悪いので。

ということで、以下のコードが現時点でのオレオレ clearfix になりました。
以下のコードでは問題があることが判明しました。

.clearfix:after{
  content: "";
  display: inline-block;
  clear: both;
}
.clearfix{
  /zoom: 1;
}

なお、Firefox 2 では、display:inline-block; に対応していないので、上記の指定ではマージンの挙動がコントロールできません。要件に組み込まれている際にはそのまま使わないように注意してください。

min-height:1%; のほうなら大丈夫みたいですが、Firefox 2 は、2008年末で開発とサポートを終了しており、アップデートできない場合は他のブラウザを使用するようアナウンスしているので、対応することはないと思います。

ブラウザの種類、バージョンでうまくいかなかったり、新しい解決方法を見つけた方は教えてください。

追記(2012年2月7日): display:inline-block; を使用した clearfix ですが、マージンの挙動がおかしくなる点については解消できますが、いわゆる clearfix として使えないことが分かりました。マージンのほうばかりに気を取られていました。すいません。

ということで、display:inline-block;display:inline-table; は、使えませんでした。
今回検証した中でちゃんと使えたのは、以下の4パターンでした。

なんとなく気持ち悪い感覚は拭えないですが、display:table; 版にしてみようかなと思います。

.clearfix:after{
  content: "";
  display: table;
  clear: both;
}
.clearfix{
  /zoom: 1;
}

こうしてみると、ほぼ A new micro clearfix hack – Nicolas Gallagher ですね。。。