masonryでコンテンツを隙間なくレイアウトする際の表示方法のバリエーションいろいろ【jQuery連載12】

前回は、グラフィックスペースをブラウザ全体を使用してグラフィカルに見せる作例を作成しましたが、今回はPinterestのようなコンテンツの内容によって一定ではなく隙間なく埋めていくレイアウトをmasonryプラグインを使用して作成してみたいと思います。

カラム(写真などコンテンツを含んだひとまとまりの要素)を一定サイズに整然と並べるのではなく、それぞれの持つ幅や高さを生かして、タイル状に隙間無く敷き詰めるレイアウトを作り、バリエーションとして横幅サイズの異なるカラムの配置や、カラム幅の相対指定方法など配置を調整することもできます。

今回作成したサンプル

【サンプル】各カラムの幅をピクセル(絶対値)指定。カラム幅は一定
http://www.html5-memo.com/sample/jq-books/06/sample1_basic.html

コンテンツを敷き詰めるプラグイン「masonry」

コンテンツを含んだカラムをタイル状にレイアウトするために、今回使用するmasonryプラグインは、要素がタイル状に自動レイアウトされるウェブサイトが話題になり始めたころからオープンソースで提供されているjQueryプラグインで、導入されたウェブサイトの事例も多くあります。

現在でもバージョンアップが重ねられていて、バージョン3ではHTML5の独自data属性に必要パラメータを設定するだけでJavascriptを一切記述しなくても導入できるなど、比較的容易に使用する事ができるようになっている。

コンテンツを配置するHTML

コンテンツを敷き詰めるサイトを作成する場合、画像だけを使用する場合や画像とテキストなどの要素を入れたいなど目的によって表示させる内容が変わるので、class(column)内に記述した内容を一つのブロックとして考えて作成していくので表示する内容を自由に調整することが可能です。

<div class="column">
<p class="photo"><img src="img/01.jpg" alt=""></p>
</div>

コンテンツを敷きつめかた:写真サイズが共通の場合

画像サイズが一定の縦横比で並べる場合は、指定した段数で一定のグリッドレイアウトで配置されるので敷き詰めるというよりは整列されたイメージで見ることができる。

この場合はmasonryプラグインを使用するまでもなく、CSSのfloatプロパティで実現可能であり、1行4列のレイアウトの場合は、画像の並び方は左から「1→2→3→4」、1段下がり再び左から「5→6→7→8」とアルファベットの「Z」字状にジグザグに配置されていく。

コンテンツを敷きつめかた:縦写真、横写真が混在する場合

縦写真、横写真が混在する場合は、floatで実装すると画像の並び方は左から「1→2→3→4」は変わらないが、図のように「3」の画像が他の画像よりも縦長の時、1段下がった後の「5」は、「3」と「4」の隙間に入り込むようなところに配置され、左側には画像が配置されないまま、大きな隙間を残してさらに1段下へ下がって一番左から「6→7→8→9」と配置されていく。このようにCSSのみでは一定の秩序を乱す要素が存在すると以後の画像の配置が不安定になり、期待しているように隙間無く画像を敷き詰める事ができない。

そこでJavascriptによってレイアウトを調整するためにmasonryプラグインを導入するわけだが、このプラグインはグリッドと同様に単に左から「1→2→3→4」、1段下がって「5→6→7→8」と並べるわけではなく、「3」のような縦長の要素があったとき、その下に来る「7」と次の「8」の縦位置を比べ、「7」の方が「8」よりも下に配置されてしまうときは本来「8」の位置に「7」を配置し、本来「7」の位置だった「3」の下に「8」を配置する。つまり、上から順番に画像の配置順(時系列順)に画像が表示されるように調整してくれます。

縦写真、横写真が混在する場合でもmasonryプラグインによって、上から順番に画像の配置順に表示されるように調整してくれます。

コンテンツを敷き詰める基本設定

今回のサンプルの1つ目(sample1_basic.html)は、masonryプラグインを適用するコンテンツ全体を格納する要素(※以後、masonryコンテナ)の幅を1080ピクセルとし、その中に格納される写真などをコンテンツ内容を含んだ要素(※以後、カラム)1つの幅を270ピクセルと絶対値で設定した。masonryは、このカラムのサイズをCSSで指定すると同時に、Javascript上でmasonryメソッドを実行する際の引数の一つ「columnWidth」にも、CSSで指定したカラムサイズと同じ値を設定しておく必要がある。このサンプルでは270を設定した。(※最新バージョンのmasonryではHTML5の独自data属性で「columnWidth」を設定する事が可能)

;(function (d, $) {

  var jQdm_flexGrid;

  jQdm_flexGrid = function () {

    // 初期設定
    var param = {
      masonryTargetContainer: $('#photoGalleryContainer'),
      itemSelector: '.column',
      loaderSymbolSelector: '.loaderSymbol' // ローダー用のCSSセレクタ
    };

    // タイル上にレイアウトする複数要素を格納した、
    // masonryプラグインを適用するコンテナ要素
    // 扱いやすいように初期設定の変数から$containerに代入
    var  $container = param.masonryTargetContainer;
    // masonryの基本設定を引数として、関数に渡し実行する
    $container.masonry({
      columnWidth: 270, // 整列用基本カラム幅(ピクセル)
      itemSelector: param.itemSelector // カラムのCSSセレクタ
    });

    // ロード中に表示するアニメーション画像の処理
    var LoaderSymbol = {
      init: function () {
        var _sel = param.loaderSymbolSelector;
        if ($(_sel).length == 0) {
          $('<div>').prependTo('body').addClass(replaceString(_sel, '€€.')).hide().fadeIn(1000);
        }
      },
      destroy: function () {
        $(param.loaderSymbolSelector).fadeOut(500,
          function () {
            $(this).remove();
            revealItems();
          });
      }
    };

    // 画像を全て読み込んだ後にmasonryを実行する
    LoaderSymbol.init();
    $container.imagesLoaded().done(function () {
      // 画像読み込み完了
      LoaderSymbol.destroy();
    });

    // 読み込んだ画像を表示する
    function revealItems() {
      var _elmes, _items;
      _elems = $container.masonry('getItemElements'),
      _items = $container.masonry('getItems', _elems);

      $container.children().css({
        visibility: 'visible'
      });
      $container.fadeIn().masonry('reveal', _items).masonry();
    }

    // 文字列置換処理
    function replaceString(_str, _bf, _af, _flg) {
      var _reg = new RegExp(_bf, _flg || '');
      return _str.replace(_reg, _af || '');
    }

  }

  jQdm_flexGrid();

})(document, jQuery);

1カラム(段・グリッド)の基本設定CSS

.grid_container .column {
  width: 266px;
  padding: 5px;
  margin: 2px;
  overflow: hidden;
  background-color: #fff;
  border: 1px solid #d9d9d9;
  visibility: hidden;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

表示させる段組の変更や全体の幅の調整

1つ目のサンプルではmasonryコンテナの幅は1080ピクセル、カラムの幅は270ピクセルとしているため横1列ごとに、1080 ÷ 270 = 4段のカラムが並ぶ計算になる。横1行ごとに並べる

段数を変更したい場合は、単純にコンテナの幅やカラムの幅を変更すれば良いが、前述のようにカラムのは幅を変更した場合は、別途Javascriptでmasonryメソッドを実行する際の引数の1つ「columnWidth」の値も変更する必要がある。

縦写真、横写真でもカラムの幅は一定にレイアウトされます。

また、表示させたブラウザのサイズを後から変更した場合には、アニメーションしながら段組が変更されるようになっています。

ブラウザサイズが小さくなり一段分が入らない場合はアニメーションしながらカラムの段数が変更される。

その他にも書籍の方ではカラムの幅を変えたり相対的なサイズ指定、画像拡大機能付などのバリエーションも作成しております。

・各カラムの幅をピクセル(絶対値)指定。カラム幅は3種類
http://www.html5-memo.com/sample/jq-books/06/sample2_multi_column.html

・各カラムの幅をパーセント(相対)指定
http://www.html5-memo.com/sample/jq-books/06/sample3_fluid_grid.html

・各カラムの幅をパーセント(相対)指定。ColorBoxプラグインによる画像拡大機能付き
http://www.html5-memo.com/sample/jq-books/06/sample4_with_colorbox.html

今回は以上になります。

次回はこういったレイアウトに関連するものとして、コンテンツを次々に読み込んで無限にスクロールするページを作成してみたいとおもいます。

この記事を書いた人

著者 : ハヤシユタカ

2001年、有限会社ムーニーワークスを設立。WEB制作の他、書籍執筆、セミナー講演、企業研修などを行う。また、クリエイター育成機関デジタルハリウッドでは1999年より講師として本科WEBデザイナーコースやデジタルデザインコースを担当。 詳しいプロフィールはこちら

最近書いた記事

この記事に関連する記事