Trusted WordPress tutorials, when you need them most.
Beginner’s Guide to WordPress
WPBカップ
25 Million+
Websites using our plugins
16+
Years of WordPress experience
3000+
WordPress tutorials
by experts

WordPressでPinterestスタイルの投稿グリッドを追加するメイソンリーの使い方

これはジョシュ・ポロックによるゲスト投稿である。

Pinterestのような投稿のグリッド表示は、しばらくの間、WordPressブログのインデックスページのデザインとして人気がある。人気のソーシャルメディアサイトの外観を模倣しているだけでなく、画面上のスペースを最大限に活用できるため人気がある。WordPressブログのインデックスでは、余分なスペースを残すことなく、各投稿のプレビューを自然に必要なサイズにすることができます。

このチュートリアルでは、人気のメイソンリーJavaScriptライブラリを使用して、ブログのインデックスやテーマのアーカイブページにカスケードグリッドレイアウトを作成する方法を紹介します。モバイル最適化のために考慮しなければならないいくつかの問題とその解決方法についても取り上げます。

Screenshot of Masonry Grid Layout in WordPress

注:このチュートリアルは、WordPressテーマの編集に慣れていて、十分なHTML/CSSの知識を持っている人向けの上級レベルです。

ステップ 1: テーマに必要なライブラリを追加する

更新: WordPress 3.9 にメイソンリーの最新バージョンが含まれるようになりました。

まず、以下のコードを使ってメイソンリーをテーマに読み込む必要があります:

[cbk1]

このコードは単純にメイソンリーをロードし、テーマのテンプレートファイルで利用できるようにします(WordPressでJavaScriptとスタイルを適切に追加する方法についてのガイドを参照してください)。また、jQuery を依存関係として追加していないことにも注意してください。メイソンリー3の利点のひとつは、jQueryを必須とせず、jQueryと一緒に使えることです。私の経験では、jQueryなしでメイソンリーを初期化する方が信頼性が高く、jQueryの読み込みをスキップできる可能性が広がるので、ページの読み込み時間と互換性の問題の両方に役立ちます。

ステップ2:Javascriptを初期化する

次の関数はメイソンリーをセットアップし、メイソンリーで使用されるコンテナを定義し、すべてが正しい順序で行われるようにします。メイソンリーはグリッドを動的にレイアウトするために、ページ上の各項目のサイズを計算する必要があります。多くのブラウザーでメイソンリーで遭遇する問題は、読み込みの遅い画像を使った項目の高さを計算ミスしてしまい、項目が重なってしまうことです。解決策としては、imagesLoaded を使用して、すべての画像が読み込まれるまでメイソンリーがレイアウトを計算しないようにします。これにより、適切なサイジングが保証されます。

これは初期化スクリプトをページフッターに出力する関数とアクションです:

[cbk2]

関数はインラインコメントでステップごとに説明されています。Javascript関数が行うことは、”masonry-entry “クラスの項目を “masonry-loop “というコンテナの中で探し、画像が読み込まれた後にのみグリッドを計算するようにメイソンリーに指示することです。外側のコンテナは querySelector で設定し、内側のコンテナは itemSelector で設定します。

ステップ2:メイソングループの作成

メイソンリー用のHTMLマークアップをテンプレートに直接追加する代わりに、メイソンリー用のテンプレート・パーツを区切りで作成します。content-masonry.php “という新規ファイルを作成し、テーマに追加します。これで、メイソングループを好きなだけ異なるテンプレートに追加できるようになります。

新規ファイルに以下のコードを追加します。このマークアップは通常のコンテンツプレビューと同じです。最後のステップでitemSelectorとして設定した “masonry-entry “のクラスが一番外側の要素にあることを確認してください。

[cbk3]

このマークアップには各パーツのクラスがあるので、あなたのテーマに一致するマークアップを追加することができます。私は、.masonry-entryに少し丸みを帯びた素敵な枠線を追加するのが好きです。.masonry-entryに枠線をつけず、少し影をつけるという設定もいい。.masonry-thumbnailのマージンとパディングをすべて0にすることで実現できます。これらのスタイルをすべて、テーマのcssディレクトリにあるmasonry.cssというファイルに追加します。

ステップ3:メイソングループをテンプレートに追加する

これでテンプレート・パーツができたので、テーマ内の好きなテンプレートで使うことができる。カテゴリーアーカイブに使用したくない場合は、index.phpには追加するかもしれませんが、category.phpには追加しないかもしれません。テーマのトップページでブログ投稿を表示させたい場合は、home.phpで使用します。どこで使うにしても、必要なことはすべて、ループを “masonry-loop” という ID のコンテナで囲み、get_template_part() を使ってテンプレート部分をループに追加することです。メイソリー・ループ・コンテナは、while (have_posts() ) の前に開始するようにしてください。

例えば、これはtwentythirteenのindex.phpのメインループです:

[cbk4]

そして、メイソンリーのループを使うように修正したのがこちらです:

[cbk5]

ステップ 4: メイソンリー項目のレスポンシブ幅の設定

各メイソンリー項目の幅を設定する方法はいくつかあります。メイソンリーを初期化するときにピクセル数を使用して幅を設定できます。私はレスポンシブテーマを使用しており、小さな画面で正しく表示するためには複雑なメディアクエリーが必須となるため、この方法はあまり好きではありません。レスポンシブデザインの場合、.masonry-entryの幅の値をパーセンテージで設定し、一列に並べたい項目の数に基づいて、残りの計算はメイソンリーに任せるのがベストだとわかりました。

このために必要なことは、テーマのstyle.cssの簡単な項目で、100を設定したい項目数で区切ってパーセンテージを設定することだけです。例えば、各行に4つの項目を配置したい場合は、メイソンリー.cssファイルにこのように記述します:

.masonry-entry{width:25%} とします。

ステップ5:モバイル最適化

ここでやめることもできるが、最終的な結果は、小さな携帯電話の画面では信じられないほどうまく機能しないと思う。デスクトップで新規メイソングリッドを使ったテーマの見え方に満足したら、スマホでチェックしてみてください。もしスマホでの見え方に不満があるようなら、少し手を加える必要がある。

スマホの画面には、私たちがコンテンツ・メーソン・リーテンプレートの部分に追加したものすべてを表示するのに十分なスペースがないと思います。スマホ用に抜粋を短くするか、完全にスキップするか、2つの良い解決策があります。テーマのfunctions.phpに追加できる関数を紹介します。これらの問題はタブレットでは問題ないと思うので、このセクションのすべての例で素晴らしいプラグインMobbleを使用して、タブレットではなく、スマホでのみ変更を加えるようにしています。また、使用する前にMobbleが有効化されているかどうかを確認し、必要であればWordPressにビルトインされているより一般的なモバイル検出機能wp_is_mobileにフォールバックしています。

[cbk6]

ご覧の通り、私たちは長い抜粋の長さと短い抜粋の長さを変数に格納することから始めます。なぜなら、これらの値を2回使用することになり、後で必要になった場合に1つの場所から変更できるようにしたいからです。そこから、Mobbleのis_phone()を使用できるかどうかをテストする。もしそうであれば、電話用の短い抜粋を設定し、そうでなければ長い抜粋を設定します。その後、同じ基本的なことを行いますが、wp_is_mobileを使用します。これは、is_phone()が使用できない場合、すべてのモバイル端末に影響します。この関数のelseの部分が使われることがないことを祈りますが、万が一に備えてバックアップを取っておくのは良いことです。抜粋の長さのロジックが設定されたら、あとはこの関数をexcerpt_lengthフィルターにフックするだけです。

抜粋を短くすることも一つのオプションですが、簡単な処理で完全になくすこともできます。以下はコンテンツメイソンの新バージョンで、携帯電話では抜粋部分がすべて省略されている:

[cbk7]

今回は、私たちが電話/モバイル端末を使っていないかどうかをテストし、もしそうであれば、ループの抜粋部分を返します。もし私たちが電話/携帯端末を使用している場合は、何もしません。

もうひとつ、モバイル端末ではメイソンリーの項目の幅を広げて、一列に並ぶ数を減らすこともできます。これを行うために、端末検出に基づいてヘッダーに異なるインラインスタイルを追加します。この関数はwp_add_inline_stylesを使用するので、特定のスタイルシートに依存します。この場合、メイソリーのスタイルを区切るためにmasonry.cssを使っています。もしそれを使わないのであれば、すでに登録されている別のスタイルシートのハンドルを使うことができます。

if ( ! function_exists ( 'slug_masonry_styles' ) ) :
function slug_masonry_styles() {
    //set the wide width
    $wide = '25%';
    //set narrow width
    $narrow = '50%';
    /**Determine value for $width**/
    //if we can only set narrow for phones, else narrow for all mobile devices
    if (function_exists( 'is_phone') {
        if ( is_phone() ) {
            $width = $narrow;
        }
        else {
            $width = $wide;
        }        
    }
    else {
        if ( wp_is_mobile() ) {
            $width = $narrow;
        }
        else {
            $width = $wide;
        }
    }
    /**Output CSS for .masonry-entry with proper width**/
    $custom_css = ".masonry-entry{width: {$width};}";
    //You must use the handle of an already enqueued stylesheet here.
    wp_add_inline_style( 'masonry', $custom_css );
}
add_action( 'wp_enqueue_scripts', 'slug_masonry_styles' );
endif; // ! slug_masonry_styles exists

この関数はカスタマイザーを呼び出し、使い慣れたロジックでwidthの値を設定します。その後、{$width}を使用して通常のCSSにwidthの値を渡すことで、変数$custom_cssを作成します。その後、wp_add_inline_styleを使って、メイソリーのスタイルシートが使われているときはいつでもヘッダーにインラインスタイルを表示するようにWordPressに指示し、関数全体をwp_enqueue_scriptsにフックして完了です。

既存のスタイルシートにメイソングリースタイルを組み込む場合は、wp_add_inline_styleでそのスタイルシートのハンドルを使うようにしてください。私がwp_add_inline_styleを使いたい理由は、メイソンリーをエンキューするためのアクションフックを条件分岐でラップし、必要なときだけ追加されるようにするためです。例えば、ブログのインデックスとアーカイブページだけにメイソンリーを使う場合、このようにします:

[cbk9]

最後のいくつかの例は、あなたの脳内で他のアイデアを広げてくれるはずだ。例えば、同様のロジックでモバイル端末ではメイソンリーを完全にスキップすることもできます。また、wp_add_inline_style()はあまり使われていませんが、とても便利な関数です。端末の検出だけでなく、どのテンプレートが使用されているか、あるいはユーザーがログイン中かどうかに基づいても、要素のスタイルを根本的に変更することができます。

私が行っているこのようなさまざまな変更は、クリエイティブになるチャンスだと捉えてほしい。メイソンリーや似たようなカスケードグリッドシステムはここしばらく人気があるので、この人気のあるアイデアに新しいひねりを加える時が来たようだ。あなたが思いついたWordPressテーマでのメイソンリーのクールな使い方をコメントで教えてください。

WordPress についての執筆、テーマ開発、Pods Framework のコミュニティ・マネージャー、そして持続可能なデザインのためのオープンソース・ソリューションの提唱など、多方面で活躍する WordPress 男性、Josh Pollock

情報開示 私たちのコンテンツは読者支援型です。これは、あなたが私たちのリンクの一部をクリックした場合、私たちはコミッションを得ることができることを意味します。 WPBeginnerの資金源 をご覧ください。3$編集プロセスをご覧ください。

アバター

This post was written by a guest contributor. You can see their details in the post above. If you'd like to write a guest post for WPBeginner, then check out our Write for WPBeginner page for details. We'd love to share your tips with our community.

究極のWordPressツールキット

ツールキットへの無料アクセス - すべてのプロフェッショナルが持つべきWordPress関連製品とリソースのコレクション!

Reader Interactions

39件のコメント返信を残す

  1. Syed Balkhi

    Hey WPBeginner readers,
    Did you know you can win exciting prizes by commenting on WPBeginner?
    Every month, our top blog commenters will win HUGE rewards, including premium WordPress plugin licenses and cash prizes.
    You can get more details about the contest from here.
    Start sharing your thoughts below to stand a chance to win!

  2. Gabi

    Hi, i wanted to know if there is a way of using the masonry grid to show registered users. Any ideas?

  3. Neil

    Just a quick note if you’re getting the “imagesLoaded” error, try adding the Javascript code after the wp_footer call in your footer.php.

    This work for me:

    Add to functions.php

    add_action( ‘wp_enqueue_scripts’, ‘slug_masonry’ );
    function slug_masonry( ) {
    wp_enqueue_script(‘masonry’); // note this is not jQuery
    }

    In your loop, make sure your div is:

    And the image class is:

    and then after wp_footer in your footer.php this:

    //set the container that Masonry will be inside of in a var
    var container = document.querySelector(‘#masonry-loop’);
    //create empty var msnry
    var msnry;
    // initialize Masonry after all images have loaded
    imagesLoaded( container, function() {
    msnry = new Masonry( container, {
    itemSelector: ‘.masonry-entry’
    });
    });

  4. Marisa Di Monda

    Hi Andy I just tried this and I couldn’t get it to work. Everything is still running vertically in one column.
    Any solutions?

  5. Marisa Di Monda

    I’m having the same problem. Did you guys solve it?

  6. Peter

    did not work for me. i see only two images on my front page which are arranged underneath. don’t know where is the problem :(

  7. Eva

    For some reason my posts will just all show just in rows like normal, not in masonry form, I’m not really sure how this can happen. Any ideas?

    • Peter

      yeah, i have the same error. any solutions for this?

  8. jcbrmn06

    For anyone still having issues with this, I noticed that this code:

    //set the container that Masonry will be inside of in a var

    var container = document.querySelector(‘#masonry-loop’);

    //create empty var msnry

    var msnry;

    // initialize Masonry after all images have loaded

    imagesLoaded( container, function() {

    msnry = new Masonry( container, {

    itemSelector: ‘.masonry-entry’

    });

    });

    Was before the masonry JS library. Therefore you get the imagesLoaded error. Like Andy suggested below putting it in the header should fix it. Basically you just have to make sure the library has to come before this code.

  9. Andy Giesler

    Thanks again for this tutorial, it really helped start me on my way.

    Even with everything in place, I saw intermittent problems where the tiles simply ran down the left of the page in a single column, and Firebug confirmed that sometimes the Masonry code didn’t execute. This happened only occasionally, and only in Firefox.

    It seemed that under certain load scenarios, there were probems with code trying to execute before the required files were loaded. I don’t think this was an imagesLoaded problem, since that has different symptoms.

    I fixed the problem as follows:

    1. The “slug_masonry_init” function places the masonry init code inline into the footer. I removed that whole function (as well as the add_action ‘wp_footer’ code) and moved the JS into an extenal file: masonry-init.js

    2. I wrapped the masonry init code in jQuery to take advantage of its document.ready ability. It’s unfortunate to pull in jQuery since this is the jQuery-free version of Masonry, but document.ready seemed necessary for the code to execute in all load scenarios.

    (function( $ ) {
    “use strict”;
    $(function() {

    });
    }(jQuery));

    3. I enqueued the scripts like this:

    wp_enqueue_script( ‘masonry’ );
    wp_enqueue_script( ‘jquery’ );
    wp_enqueue_script( ‘masonryInit’, get_stylesheet_directory_uri().’/js/masonry-init.js’, array( ‘masonry’, ‘jquery’ ) );

  10. Daniel Nikolovski

    Done exactly as the tutorial says, wp 3.9.1.. imagesLoaded isn’t even being loaded. Some help would be highly appreciated

  11. Tiago Celestino

    This , where is define ‘masonry-thumb’?? this default thumbnail size with masonry Wordpress?

  12. Jenny Beaumont

    I’m having trouble getting this to work…followed things accordingly, based on _s, but my columns don’t wrap – just get one long one. Have any css examples to go with? I’m obviously missing something. cheers!

    • marisa

      Hi Jenny

      I am having the same trouble. Did you solve your problem?

  13. caratcake

    I’m desperately confused. I performed every step down to the letter, and my site just goes blank. A problem with the functions file. My browser doesn’t even allude to which line causes any error, all I get is ”
    Server error
    The website encountered an error while retrieving (url) It may be down for maintenance or configured incorrectly.”

    The same happened for the WP Admin login page. I deleted functions.php in my theme folder, and the login screen was restored, but the front page was not. If you could give me any clues to what the problem might be, I would be very grateful. Regardless, many thanks for the tutorial and in depth explanations.

  14. Andy Giesler

    In case this helps others to get the sample working:

    It wasn’t working for me even after I made the fix that others have noted — changing “function slug_masonry_exists()” to “function slug_masonry_init()”. The libraries were being loaded, but Masonry wasn’t doing its thing.

    Then I changed the wp_enqueue_script calls so that Masonry and imagesLoaded got loaded in the header instead of at the bottom.

    Suddenly everything worked.

    • Jean

      Hi, i can´t figure out how do change the wp_enqueue_script. I will really appreciate if you can explain that in detail. Thanks!

  15. gabi

    Hello, It doesn’t work for me I have this error message :
    ” Parse error: syntax error, unexpected T_ENDIF in…”…functions.php on line 17

    It means an error on the script from the 3td step. What did I miss ?

  16. werner

    Will you update your post due to the fact that now with 3.9 Masonry3 is in Wordpress core?

  17. Steven Gardner

    The initialization script keeps being called before imagesloaded has been defined so I get

    Uncaught ReferenceError: imagesLoaded is not defined

    How can I make sure imagesLoaded is there first before I start to initialise things?

    • Violacase

      imagesLoaded is called before enqueueing has been established. Give it a low priority so that it is called last, like:

      add_action( ‘wp_footer’, ‘slug_masonry_init’, 100000 );

      This did the trick for me.

      Nota: I think this article needs to be updated. Not only because of this issue.

      • Chplusink

        Thanks! This is the only solution that worked for me.

  18. Kate

    Thanks for this post. I am trying to set up a blog page with Masonry posts, but I’m snagged at step 1. Whenever I add the functions for adding the two libraries to my functions file, my site goes totally blank. Since I am developing in a subdirectory, I tried to make the paths to the js files absolute rather than relative, but that didn’t help. Any idea what I’m missing?

  19. Angie Lee

    Hi,

    I’m getting this error: “ReferenceError: imagesLoaded is not defined” please help.

  20. Amitabha Ghosh

    Thanks. It’s a great post and it is working for me. I am doing a template with this code and it is working perfect. But two obstacles I am facing
    1. I want to limit my posts in my index page so that it shows first 6 to 7 posts and below will be a button with “Load More” feature which when clicked shall load the other posts.

    2. I am trying to integrate infinite scroll javascript of Paul Irish but I couldn’t make it work. Any help??

    Thanks

  21. Ismar Hadzic

    Well I followed all of your steps and I run on fatal error ” PHP Fatal error: Call to undefined function wp_enquqe_style() ” and i still don’t understand why wp_enquqe_style() i don’t understand why can you check that out.

    • AndyM

      Hi

      I was going to comment to point out that it’s a typo and should be:

      wp_enqueue_style

  22. Andre

    Great tutorial…just one thing in step 3…this:

    …has a missing bracket:

  23. Aurélien Denis

    Hi there!

    This post is great start but I found some mistakes…

    1/ You should use the_title_attribute() for the attribute title instead of the title
    2/ add_action( ‘wp_footer’, ‘slug_masonry_exists’ ); is the correct code and not add_action( ‘wp_footer’, ‘slug_masonry_init’ );

    Cheers!

    • AndyM

      I’m wondering if

      if ( ! function_exists( ‘slug_masonry_init’ )) :
      function slug_masonry_exists() { ?>

      should be:

      if ( ! function_exists( ‘slug_masonry_init’ )) :
      function slug_masonry_init() { ?>

  24. Ben Racicot

    Can’t get this working with an infinite scroll setup in my $ajax success CB. Any advice would be great.

  25. Tomasz Bystrek

    I was looking for this effect, but I did’t know how it is called and how to search for it, until now. I’ll definitely try it in one of my future project of photo blog. Thanks!

  26. Katrina Moody

    Great post – wish it was around when I started working with Masonry on a theme a few weeks ago :D

    A couple variations – I created a new post-thumbnail image size to pull in so that both horizontal and vertical images would have equal attention within the Masonry pages – it’s fairly easy to change out the actual image for a new one (I did that at first, creating a new “entry-thumbnail” size and allowing unlimited length so that horizontal images would display properly). Then I just edited the post-thumbnail ;-)

    I also wrapped the post-thumbnail within an tag so that I could allow it to return to the post permalink (I changed that out to return the media file link so I could implement a lightbox effect – per a client’s request) so visitors could go directly to the post.

    I also added a hover effect to the post-thumbnail to indicate it was clickable :D

    Now I need to pick through what I’ve done and compare it to yours and see what I can improve with your knowledge (love the WordPress community!)

    • Ivan Vilches

      guys all that code is on functions.php ? thanks

返信を残す

コメントありがとうございます。すべてのコメントは私たちのコメントポリシーに従ってモデレートされ、あなたのメールアドレスが公開されることはありませんのでご留意ください。名前欄にキーワードを使用しないでください。個人的で有意義な会話をしましょう。