2010-12-04

異なる高さのブロックの高さを揃えるスクリプト まとめ

異なる高さのブロックの高さを揃えようとすると、CSS だけでは制御できなかったり面倒だったり…なので、ここは JavaScript の力を借りることに。

jQuery 非依存のもの

今は jQuery に頼ることが多いですが、他のライブラリなどとの相性で使えない場合などもあるかと思うので、まずはjQuery 非依存のスクリプト。

heightLine.js

ブロックレベル要素の高さを揃えるheightLine.js[to-R]

読み込む JavaScript は1つ。
スクリプトまでのパスは適宜変更してください。

<script type="text/javascript" src="path/heightLine.js"></script>

指定方法1

heightLine という class を指定した要素の高さが揃います。

<div class="sample">
    <div class="heightLine">
        <p>sample</p>
        <p>sample</p>
    </div>
    <div class="heightLine">
        <p>sample</p>
    </div>
</div>

指定方法2

heightLine の後ろに -(ハイフン)と好きなグループ名を付けた class を指定すると、各グループで高さが揃います。

<div class="sample">
    <div>
        <p class="heightLine-group1">sample<br />sample</p>
        <p class="heightLine-group2">sample</p>
    </div>
    <div class="heightLine">
        <p class="heightLine-group1">sample</p>
        <p class="heightLine-group2">sample<br />sample<br />sample</p>
    </div>
</div>

指定方法3

heightLineParent という class を指定した要素の子要素の高さが揃います。

<div class="heightLineParent">
    <div class="sample1">
        <p>sample</p>
        <p>sample</p>
    </div>
    <div class="sample2">
        <p>sample</p>
    </div>
</div>

状態によっていろいろな指定方法ができ、便利なスクリプトですが、1秒ごとに文字サイズを取得して高さの再計算を行なうため、拡縮のタイミングと若干ズレが生じます。
待てばちゃんと高さが揃うので問題ないのですが、気になる人はここが気になるかもしれません。
なお、このスクリプトは MIT ライセンスで公開されています。

jQuery プラグイン

いろいろなものがあるようですが、ここ最近使った2つ紹介。

fixHeight.js

複数のブロック要素の高さを揃えてくれる「fixHeight.js」をアップデートしました | Blog | STARRYWORKS inc.

jQuery プラグインなので、jQuery と fixHeight.js を読み込んで置く必要があります。
スクリプトまでのパスは適宜変更してください。

<script type="text/javascript" src="path/jquery.js"></script>
<script type="text/javascript" src="path/fixHeight.js"></script>

指定方法1

fixheight という class を指定した要素の子要素同士の高さが揃います。
下の例の場合、fixheight の子要素である sample1と sample2の高さが揃います。

<div class="fixheight">
    <div class="sample1">
        <p>sample</p>
        <p>sample</p>
    </div>
    <div class="sample2">
        <p>sample</p>
    </div>
</div>

子要素が多く、子要素が2行以上になった場合には、全要素の高さを揃えるのではなく、各行の中で高さが揃います。

指定方法2

fixHeightChild という class を指定した要素同士の高さが揃います。

<div class="sample">
    <div class="fixHeightChild">
        <p>sample</p>
        <p>sample</p>
    </div>
    <div class="fixHeightChild">
        <p>sample</p>
    </div>
</div>

指定方法3

fixHeightChild のあとに任意の文字列を繋げた class が指定された要素同士の高さが揃います。
下の例の場合、fixHeightChildParagraph が指定された p タグの高さが揃います。

<div class="sample">
    <div>
        <p class="fixHeightChildParagraph">sample</p>
        <p>sample</p>
    </div>
    <div>
        <p class="fixHeightChildParagraph">sample<br />sample</p>
        <p>sample</p>
    </div>
</div>

先に挙げた heightLine.js とほぼ同じ指定の仕方で指定できます。
なお、このスクリプトは MIT ライセンスで公開されています。

jquery.flatheights.js

jQuery でブロック要素の高さを揃えてみる – 徒書

こちらも jQuery プラグインなので、jQuery と jquery.flatheights.js を読み込んで置く必要があります。
スクリプトまでのパスは適宜変更してください。

<script type="text/javascript" src="path/jquery.js"></script>
<script type="text/javascript" src="path/jquery.flatheights.js"></script>

上記2つのスクリプトを読み込み、高さを揃えたい要素に対し、flatHeights() メソッドを実行します。

指定方法1

$() の中は jQuery で指定できる形式ならなんでも指定できるよう。
カンマ区切りでの複数の指定ももちろんできます。

$(function(){
    $('.boxes').flatHeights(); // .boxes が付けられた要素の高さが揃う
    $('#box1 > div').flatHeights(); // #box1 の子要素(例では div)の高さが揃う
    $('#box2, #box3, #box4').flatHeights(); // 指定した要素同士の高さが揃う
});

指定方法2

各行で要素の高さを揃えたい場合、fixHeight.js は自動でやってくれましたが、jquery.flatheights.js はちょっと指定が複雑になります。
例は各行が4つずつの場合。

$(function(){
    var sets = [], temp = [];
    $('#box5 > div').each(function(i){
        temp.push(this);
        if (i % 4 == 3){ // 1行の数を指定し、1を引いた数を右に指定
            sets.push(temp);
            temp = [];
        }
    });
    if (temp.length) sets.push(temp);

    $.each(sets, function(){
        $(this).flatHeights();
    });
});

先に挙げた2つとの違いは既存の HTML で使用する際にスクリプト用の指定を追記をしなくていいということ。
適用される範囲を調整するために id や class の追記が必要な場合もあるかもしれませんが、基本的には指定を追加しなくて大丈夫です。
なお、このスクリプトは MIT ライセンスで公開されています。

まとめ

jQuery プラグインのものは初めて使ったものが動作が遅く、heightLine.js を使用することがほとんどでしたが、上で挙げた2つのプラグインはそこまでのもたつきは感じなかったです。
また、秒ごとの監視ではなく、文字の拡縮動作を監視し、動作があったときに高さが変わるので、最近は jQuery プラグインのものを使うことが多いです。

今回紹介した jQuery プラグイン2つの大きな違いは適用される箇所の指定を HTML 側で指定するか、JavaScript 側で指定するかです。
僕は HTML 側に直接いろいろと class を追加するのが好きじゃないので、jquery.flatheight.js を使うことが多いです。

JavaScript を使用することで、泣く泣く変更をお願いしていたようなデザインが実現できるようになることもあるので、作者の方々に感謝の言葉しか出てきません。ホント助かってます。ありがとうございます。

他にもこんな素晴らしいプラグインがあるよという方はぜひぜひ教えてください。