あと味

たくさん情報を食べて、たくさん発信すると、あとになって味わい深い。

JavaScriptでclearfixみたいなものを実装する実験

clearfixの記述を見てて、contentプロパティで内容追加して、blockにして、高さを消すとかやってるので、JavaScriptでもできるんじゃね?と思ったら、実際できたので、実用性は抜きにしてメモとして投稿しておきます。

CSSでのclearfixの記述

いろいろあるみたいですが、ヨモツネットさんの記事から拝借します。

こんな感じに書きます。

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

フロートした子要素を持つ親要素の内容の末尾(要するに子要素)に、contentプロパティで内容を作ります。

その内容はclear: both;するためだけのものなので、height: 0;にして見えなくしちゃいます。display: block;はheightを指定するためかな?ちょっとそこら辺は曖昧ですけどそんな感じです。clearプロパティはブロックレベル要素に付けることを求められてるからそれが理由か。

後は、after擬似要素*1に対応していないIE6,7のために、\zoom: 1;してやることで、hasLayoutの値をtrueにします。フロートされた要素は、親要素の高さ計算に使われない仕様ですが、IEではhasLayoutの値がtrueだと、計算に含めてくれるみたい。

widthに値を指定しても、hasLayoutがtrueになるって書いてあるけど、子要素をfloatしたらhasLayoutがfalseに上書きされるってことかしら。それをさらにtrueに上書きするということかな。

HTMLとCSSのサンプル

<div id="parentBox" class="clearfix">
  <div id="childrenBoxA">
    ...
  </div>
  <div id="childrenBoxB">
    ...
  </div>
</div>

こんな感じのHTMLをclearしようと思った場合、CSSではこう書きます。

#parentBox {
  width: 800px;
}

#childrenBoxA {
  width: 300px;
  float: left;
}

#childrenBoxB {
  width: 500px;
  float: right;
}

.clearfix {
  /zoom : 1; 
}

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

HTMLとCSSJavaScriptのサンプル

上記サンプルと同じような原理で、JavaScriptを記述してみます。

jQuery読み込んでるケースが多いと思うので、JavaScriptの部分はjQueryで実装することにしました。

HTML
<div id="parentBox">
  <div id="childrenBoxA">
    ...
  </div>
  <div id="childrenBoxB">
    ...
  </div>
</div>
CSS
#parentBox {
  width: 800px;
}

#childrenBoxA {
  width: 300px;
  float: left;
}

#childrenBoxB {
  width: 500px;
  float: right;
}
JavaScript(jQuery)
// メソッドの定義
jQuery.fn.extend({
  clearfix: function() {
    return this.append($(document.createElement('div')).css('clear', 'both'));
  }
});

// jQueryによる処理
$(function() {
  $('parentBox').clearfix();
});

jQueryの部分の解説をすると、空のdiv要素を作って、そいつにclear: both;のstyleを持たせて、メソッドの呼び出し元になってる要素の内容の末尾にそいつを追加するという処理。単純なものなので、IE6とかでもちゃんと動きます。

今さらだけど、これだとclearfixとは呼ばないのかもしれない。

メソッドチェーンを切らないようにreturnしてるけど、不要であればreturnの記述はいりません。

個人的にはHTMLとCSSがスッキリして楽です。とは言え、パフォーマンス悪いし、JavaScript切られた環境だと壮大なレイアウト崩れを起こすし、所詮臭いものに蓋をする的な発想に過ぎないので、実践で使うことはなく、実験にとどまりますね。

以上、実験メモでした。

*1:これ、俺も勘違いしてたんですけど、動作的には:pushとか:appendって名前の方がわかりやすいですね。