Masonryを使ってdivをタイリングする

先日、ODプロジェクト総合ウェブサイトのトップページのデザインを修正しました。

段組のレイアウトにするためfloatを使って配置していたのですが、その途中、特定の条件下でデザインが大きく崩れてしまうという問題に直面。
それについての簡単な説明と、僕が取った解決策を以下に記しておきます。

まずは、ざっくりと。

ブロック要素(div等)をを並べて記述すると、縦に連なって表示されることが多いと思われます。
ここでCSSの float:left を指定すると、左から順番に並ぶよう配置されます。

ブロック要素にfloat:leftを指定する(1)
ブロック要素にfloat:leftを指定する(1)

ブラウザの表示領域の右端に到達すると、次からは下に移動します。
ここでは、ブラウザのウィンドウサイズを変更して、その状態を発生させています。
ブロック要素にfloat:leftを指定する(2)
ブロック要素にfloat:leftを指定する(2)

綺麗にタイリングされていますね。
固定デザインには向きませんが、ユーザの環境に合わせて見た目が変化するウェブページの完成です。
ここまでは特に問題ありません。

異なるサイズのブロックを並べる

ですが、これが異なるサイズの場合はどうなるでしょうか。

高さの異なるブロック要素を並べる
高さの異なるブロック要素を並べる

例えばこのような、高さ(height)が異なるブロック要素を用意します。
先ほどと同じように、ウィンドウ幅を狭めてみましょう。

しまった! バラバラに配置されてしまった!
しまった!バラバラに配置されてしまった!

ご覧の通り、酷いことになっています。

もう少し見てみましょう。
1番(赤色)~3番ブロック(黄色)が一列配置され、そこで右端に到達します。
そして4番(緑色)が改行されるわけですが、左端である1番ブロックの下ではなく真下に置かれてしまっています。
これは縦に長い2番ブロック(オレンジ色)に阻まれてしまっている、と考えられます。

同様に5番(水色)と6番(青色)も、2番が邪魔になっています。
6番は上端がほんの少し引っかかっているだけですが、それでもダメです。
そして7番(ピンク色)になって、ようやく阻む物が無くなったので左端に配置されるわけですが、かえってそれが妙な空白を生み出してしまっています。

このレイアウト崩れが気になる場合、手作業で順番や高さを調整すれば良いことになります。
せっかくですし、何か自動的に解決してくれる方法が無いか探してみましょう。

Masonryを導入してみる

……と、探してみましたら、割とあっさり見つかりました。
MasonryというJavaScriptライブラリです。有名みたいですね。
ちなみにMasonは石工という意味らしいです。まさにタイル貼りといったところでしょうか。

JavaScriptライブラリのデファクトスタンダードであるjQueryを導入していれば、このMasonryはプラグインとして簡単に扱うことが出来ます。
もちろん、単独でのMasonry導入も可能とのことです。

[js title=”ヘッダ部分” htmlscript=”true”]
<head>
<script src="jquery-1.10.2.min.js"></script>
<script src="masonry.pkgd.min.js" ></script>

<script>
$(function()
{
//タイリング設定
$(‘article’).masonry(
{
itemSelector: ‘.itemSelector’,
columnWidth: 100, //width,margin,border等の合計
});
});

</script>
</head>
[/js]
2~3行目:
scriptタグでjQueryとMasonryライブラリを読み込みます。

6行目~:
jQuery向けのコードです。

9~13行目:
Masonryの設定を記述しています。
ここでは、HTMLソース内の article 要素をレイアウト領域全体とし、その中のitemSelectorクラスを実際に配置するブロックとしています。
また、columnWidth は1カラムの横幅です。ブロックの横幅にマージン等を加算した数値を記述します。

[html title=”本文”]
<article>
<!–タイリングするブロック–>
<div class="itemSelector"> 01 </div>
<div class="itemSelector"> 02 </div>
<div class="itemSelector"> 03 </div>
<div class="itemSelector"> 04 </div>
<div class="itemSelector"> 05 </div>
<div class="itemSelector"> 06 </div>
<div class="itemSelector"> 07 </div>
</article>
[/html]

続けて Body 内を以上のようにコーディングします。
article タグや itemSelector クラスにしていますが、設定さえすれば何でもOKです。
すると、以下のようなレイアウトになります。(実際には更に色指定などを追加しています)

Masonryによるレイアウト
Masonryによるレイアウト

だいぶ整いましたね!
どうやらこちらは、その時点で一番高さの合計が低いカラムを探し(同値の場合は左側を優先)、その下に配置する……というアルゴリズムのようです。

もちろんこれは極端な例ですが、それなりの効果を望めると思います。

注意点など

画像読み込みのタイミング

Masonryでのレイアウトには、各カラムの高さ情報が必要となります。
そのため、画像ファイル等を読み込む場合は、ロードのタイミングによっては綺麗に配置されません。
imgタグにwidth/heightを設定したり、あるいは読み込み完了を検知するライブラリを別途導入するなどで回避できるとのことです。

padding設定

itemSelectorで指定したブロック要素に対し、CSSでpaddingの値を設定しようとしたところ、上手く行きませんでした。
理由は分かりませんが、このブロック要素の内部に更に

タグでブロックを作り、そちらにmarginなりpaddingなりを設定することで解決できました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です