< Заур Магомедов />

профессиональный верстальщик и блоггер

Мое хобби - разработка сайтов, но со временем это переросло в постоянный и стабильный источник дохода.

Заур Магомедов
Главная » Приятные полезности для сайта » Masonry Layout — кирпичный эффект элементов на сайте. Документация на русском языке

Masonry Layout — кирпичный эффект элементов на сайте. Документация на русском языке

Masonry Layout — кирпичный эффект элементов на сайте. Документация на русском язык

Пост был обновлен: Дек 15, 2016

Доброго времени суток всем! Это моя вторая статья в этом году. Первую про иконочный шрифт я опубликовал совсем недавно и меня радует, что я нашел время для написания второй статьи с таким небольшим отрывом. Пока для меня это небольшой отрыв, т.к. чаще писать нет возможности, но я стараюсь.  😎 А теперь давайте разберемся о чем пойдет речь в этой статье.

Быть может многие из вас видели на сайтах расположение элементов (картинок, статей, различных блоков) кирпичным эффектом. Вы скажите — это же можно и через CSS сделать? Может и можно, но только такой гибкости не будет. Скрипт сам расставляет элементы на странице, используя вертикальное пространство. Также при позиционировании блоков скрипт добавляет анимацию. Пронаблюдать это можно в адаптивном дизайне, уменьшая окно браузера. Так вот, достигается это все с помощью небольшой javaScript-библиотеки — Masonry. Данный скрипт очень широко используется в современных трендовых дизайнах. Не знаю как в русско-язычном, но в зарубежном интернете Masonry получил большую популярность.

Автором Masonry является David DeSandro из США. Хотелось бы сказать ему большое спасибо за такой хороший скрипт. Распространяется данная библиотека абсолютно бесплатно, так что смело можете использовать ее на своем сайте. Но сначала давайте посмотрим на некоторые примеры работы Masonry.

Я думаю многим понравилось. На самом деле все очень красиво смотрится. Давайте разберемся как работать с Masonry, как вывести на нашем сайте наши блоки кирпичным эффектом?

Для начала нам необходимо перейти на страничку скрипта — http://masonry.desandro.com и скачать последнюю версию. На момент написания данной статьи это версия — 4.0. Также на данном сайте вы найдете подробную документацию на английском языке. Я ниже разберу основные моменты из документации — как подключать, какие имеются опции и т.д. Все затрагивать не буду, т.к. я сам в некоторых моментах еще не разобрался. Для внедрения на свой сайт требуется сделать минимум действий. Вы сейчас в этом убедитесь.

На сайте для скачивания имеются две версии скрипта — сжатая (минимизированная) и несжатая. Лучше использовать именно сжатую — masonry.pkgd.min.js. Также библиотеку можно подгрузить и из CDN:

несжатая

<script src="https://npmcdn.com/masonry-layout@4.0/dist/masonry.pkgd.js"></script>

сжатая (минимизированная)

<script src="https://npmcdn.com/masonry-layout@4.0/dist/masonry.pkgd.min.js"></script>

Советую подключить минимизированную версию Masonry из CDN. Так мы уменьшим количество ненужных http-запросов. Вообще, какой бы вы скрипт не подключали, если есть возможность подключить минизированную версию с CDN, то подключайте именно ее.

Для работы Masonry нам необходимо создать родительский блок и положить в него сами элементы.

Для наглядности я создал демо-страничку с картинками разных размеров. В качестве примера элементов я взял именно картинки, т.к. они имеют разную высоту, но вместо картинок может быть любой блок: текст, видео и др. Попробуйте уменьшить окно браузера и вы увидите, как картинки плавно меняют свою позицию.

Давайте посмотрим как будет выглядеть html-код:

<div class="elements-gride">
 <img class="element-item" src="/images/img1.jpg" />
 <img class="element-item" src="/images/img2.jpg" />
 <img class="element-item" src="/images/img3.jpg" /> 
 ...
 </div>

CSS-код:

#container {
    border: 1px solid #ccc;
    margin: 0 auto;
    padding: 50px 0;
    max-width: 1170px;
}
/* Элемент сетки */
.element-item { 
    border: 2px solid rgba(0, 0, 0, 0.35);
    margin-bottom: 15px;
    padding: 1px;
    width: 280px
}
/* /элемент сетки */
h1 {
    text-align: center;
    margin: 0 0 50px
}

Как видим, css используется здесь по минимуму.

Инициализируем плагин Masonry

Сделать это можно несколькими способами.

Инициализация Masonry через javaScript

Вы можете использовать Masonry как jQuery-плагин:

$('selector').masonry();

Но имейте ввиду, что для этого метода у вас должна быть подключена библиотека jQuery:

<script src="https://code.jquery.com/jquery-2.1.4.js"></script>

На демо-страничке я инициализировал Masonry, как jQuery-плагин, т.е. код инициализации у меня следующий:

jQuery(document).ready(function($) {
    $('.elements-gride').masonry({
        // options
        itemSelector: '.element-item',
        columnWidth: 300
    });
});

Если вы обратили внимание методу «masonry()» мы передали две опции: ItemSelector и columnWidth. Это обязательные две опции. По словам разработчика они необходимы для нормальной работы скрипта. Впрочем, об опциях мы поговорим чуть ниже. Все, после этих действий должно все работать.

Инициализация с помощью Vanilla JavaScript

Вы можете использовать Masonry также и с Vanilla JS:

new Masonry( elem, options )

Конструктор Masonry() принимает два аргумента: дочерний элемент контейнера и опции объекта. Код инициализации будет следующий.

var elem = document.querySelector('.elements-gride');
var msnry = new Masonry( elem, {
// options
itemSelector: '.element-item',
columnWidth: 200
});

// element argument can be a selector string
// for an individual element
var msnry = new Masonry( '.elements-gride', {
// options
});

Честно говоря, не работал с Vanilla JS поэтому конкретно не могу сказать чем он хорош, чем jQuery. Просто знайте, что есть такой метод.

Читайте также:  Анимированная кнопка для формы на чистом CSS

Инициализация через HTML

Вы можете инициализировать Masonry через HTML, не написав ни единой строчки javaScript кода. Для этого понадобится добавить всем дочерним элементам контейнера атрибут — «data-masonry». Опции можно передать, в качестве значения.

<div class="elements-gride" data-masonry='{ "itemSelector": ".element-item", "columnWidth": 200 }'>
Передаваемые параметры должны соответствовать формату JSON. Хочу обратить ваше внимание на использование кавычек в коде. Кавычки для атрибута data-masonry пишутся одинарными, а для передаваемых опций — двойные. Т.е. именно так, как показано на примере.

Данный вариант можно использовать, если вы не хотите использовать на сайте лишний javaScript. Например, я бы не стал лишний раз грузить jQuery, если на сайте он у меня нигде не используется.

Вот такая вот библиотека. Ничего сложного нет. А что дальше?

Если обратиться к документации, то дальше идет разбор: размеры элементов контейнера, опции, события, методы.

Размеры элементов

Размеры дочерних элементов могут быть как фиксированными, так и резиновыми. При фиксированном размере (ширина и высота) элементов ширина блоков и их оформление задается в пользовательском css-файле стилей. По высоте хочу сказать, если вы используете не пустые блоки, то высота блока будет высчитываться браузером, исходя из его содержимого. В моем случае я высоту не задаю, т.к. картинки итак имеют свою высоту.

<div class="elements-gride">
    <img class="element-item" src="/wp-content/demos/masonry/demo-masonry/images/img1.jpg" />
    <img class="element-item" src="/wp-content/demos/masonry/demo-masonry/images/img2.jpg" />
    <img class="element-item" src="/wp-content/demos/masonry/demo-masonry/images/img3.jpg" />    
    ...
</div>
.element-item {
    padding: 2px;
    width: 280px
}
jQuery(document).ready(function($) {
    $('.elements-gride').masonry({
        // options
        itemSelector: '.element-item',
        columnWidth: 280
    });
});

Резиновая сетка

При резиновой сетке ширина элементов задается в процентах. Резиновую сетку в основном используют в адаптивном дизайне. Подробнее об опциях поговорим ниже.

<div class="elements-gride">
    <img class="element-item persent-size" src="/wp-content/demos/masonry/demo-masonry/images/img1.jpg" />
    <img class="element-item persent-size" src="/wp-content/demos/masonry/demo-masonry/images/img2.jpg" />
    <img class="element-item persent-size" src="/wp-content/demos/masonry/demo-masonry/images/img3.jpg" />
 ...
</div>
.element-item {
    padding: 2px;
}
.persent-size {
    width: 25%
}
jQuery(document).ready(function($) {
    $('.elements-gride').masonry({
        // options
        itemSelector: '.element-item',
        columnWidth: '.persent-size',
        percentPosition: true
    });
});

ImagesLoaded

Иногда при загрузке страницы может случиться так, что элементы будут перекрывать друг друга. При этом они собираются все в один комок и смотрится все ужасно. Так вот решить эту проблему можно с помощью небольшой библиотеки — imagesLoaded. Наиболее хорошо это проявилось у меня при адаптивном дизайне. Именно, когда я сайт открывал с мобильного телефона сетка изображений у меня собиралась в одну кучу.

Подключаем imagesLoaded с CDN:

<script src="https://npmcdn.com/imagesloaded@4.1/imagesloaded.pkgd.min.js"></script>

С помощью imagesLoaded элемент позиционируется на странице только после полной его загрузки.

// init Masonry
var $grid = $('.grid').masonry({
    // options...
});
// layout Masonry after each image loads
$grid.imagesLoaded().progress( function() {
    $grid.masonry('layout');
});

Или инициализация Masonry происходит только после полной загрузки всех изображений.

var $grid = $('.grid').imagesLoaded( function() {
    // init Masonry after all images have loaded
    $grid.masonry({
        // options...
    });
});

Опции (Options)

Теперь давайте разберем какие мы можем передать опции методу masonry().

Все опции сгруппированы. Ну, это сделано, чтобы легче было в них ориентироваться.

Теперь давайте посмотрим какие опции входят в определенную группу.

itemSelector

Данная опция указывает к каким элементам будет применяться эффект Masonry. Полезно указывать данную опцию, потому что тем самым мы можем отсечь элементы которые не являются частью макета. Этот параметр нам уже знаком, когда мы разбирали инициализацию Masonry.

itemSelector: '.element-item'

columnWidth

Задает ширину элементов макета. Если данный параметр опустить Masonry возьмет внешнюю ширину первого элемента. Разработчик всегда советует указывать ширину колонок, будь то элементы фиксированные или резиновые.

columnWidth: 80

Размеры элементов (Element sizing)

Если мы хотим сделать наш макет с элементами резиновым, например, при адаптивном дизайне, то для этих целей предусмотрен параметр, который делает нашу сетку резиновой.

percentPosition

Код резиновой сетки мы разбирали выше, но в подробности опций не вдавались.

<div class="elements-gride">
    <img class="element-item persent-size" src="/wp-content/demos/masonry/demo-masonry/images/img1.jpg" />
    <img class="element-item persent-size" src="/wp-content/demos/masonry/demo-masonry/images/img2.jpg" />
    <img class="element-item persent-size" src="/wp-content/demos/masonry/demo-masonry/images/img3.jpg" />
 ...
</div>
.element-item {
    padding: 2px;
}
.persent-size {
    width: 25%
}
jQuery(document).ready(function($) {
    $('.elements-gride').masonry({
        // options
        itemSelector: '.element-item',
        columnWidth: '.persent-size',
        percentPosition: true
    });
});

Как видим, чтобы активировать резиновую сетку мы добавили параметр percentPosition в код инициализации с булево значением «true«. А в качестве ширины указали класс элемента, которому в css присвоена ширина в процентах.

gutter

Между элементами можно задать отступ по горизонтали с помощью опции gutter, передав число. Число будет соответствовать отступам в пикселях.

gutter: 15

Отступы по вертикали между элементами задаются в css.

.element-item {
    margin-bottom: 15px;
}

Отступы можно задать и в процентах, т.е. они будут меняться в зависимости от размера окна браузера.

<div class="elements-gride">
 <div class="gutter-width"></div>
 <img class="element-item persent-size" src="/wp-content/demos/masonry-responsive/images/img1.jpg" />
 <img class="element-item persent-size" src="/wp-content/demos/masonry-responsive/images/img2.jpg" />
 <img class="element-item persent-size" src="/wp-content/demos/masonry-responsive/images/img3.jpg" />
...
</div>
.element-item {
 margin-bottom: 15px;
 padding: 2px;
}
.gutter-width {
 width: 4%
}
.persent-size {
 width: 22%
}
jQuery(document).ready(function($) {
    $('.elements-gride').masonry({
    // options
    itemSelector: '.element-item',
    columnWidth: '.persent-size',
    gutter: '.gutter-width',
    percentPosition: true
   });
});

Мы создали пустой DIV-блок перед списком элементов.

<div class="gutter-width"></div>

В CSS для данного блока указали ширину в процентах. А в коде инициализации опции gutter мы указали класс данного пустого элемента. Скрипт сам создаст отступы в процентах, исходя из ширины данного блока.

stamp

Данной опцией можно назначить элементы, которые будут штампованы в сетке Masonry. Остальные элементы будут находиться ниже и будут обтекать штампованные. Иногда это может быть полезным. Опции stamp передаем класс штампованного элемента.

stamp: '.stamp'

21933

Детальнее пример вы можете посмотреть на Codepen, а также отредактировать при необходимости.

fitWidth

Суть данной опции состоит в том, что когда мы ее активируем родительскому блоку элементов добавляется фиксированная ширина в пикселях. Причем ширина родительского блока равна сумме ширин всех дочерних элементов. Таким образом, указав в css родительскому блоку правило «margin: 0 auto» мы можем расположить блок с элементами Masonry по центру.

.elements-gride {
    margin: 0 auto;
}
isFitWidth: true
Внимание! Данная опция не работает с элементами, ширина которых указана в процентах. Значение опции «columnWidth» должно быть указано в пикселях, например, «columnWidth: 120». Иначе, элементы могут налезть друг на друга.

21933

originLeft

По умолчанию все элементы сетки выравниваются слева на право. С опцией originLeft можно изменить горизонтальный поток элементов и задать выравнивание справа налево. Достаточно передать булево значение «false».

originLeft: false

21933

originTop

Также как и по горизонтали по умолчанию элементы сетки выравниваются по верхнему краю. С опцией originTop можно изменить поток элементов по вертикали и задать выравнивание снизу вверх, примерно как в тетрисе 🙂 .

originTop: false

21933

Настройки (Setup)

Переходим к опциям настроек.

Читайте также:  RSForm - ajax отправка форм без перезагрузки страницы

containerStyle

Данная опция отменяет стили родительского контейнера элементов. По умолчанию родителю задается правило «position: relative». Данное правило можно отменить.

containerStyle: null

Конечно, можно было и переопределить через файл CSS с помощью «!important», но я не люблю так делать. Вообще я считаю это правило дурного тона в верстке. Лучше все же очистить стили, тем более разработчик дает нам такую возможность.

transitionDuration

Продолжительность перехода, когда элементы меняют свое местоположение. По умолчанию задано время — 0.4 сек. Формат времени задается, как формат времени CSS.

transitionDuration: '0.4s'

Вот некоторые примеры установки времени.

// Быстрая анимация
transitionDuration: '0.2s'

// Медленная анимация
transitionDuration: '0.8s'

// Нет анимации
transitionDuration: 0

resize

C помощью данной опции можно отменить изменение размеров родительского блока. Т.е. по умолчанию, если не задать фиксированный размер родителю при уменьшении экрана браузера наши дочерние элементы сетки будут менять свое месторасположение, будут перемещаться вниз, занимая свободное пространство. Так вот с помощью опции «resize» можно отменить переходы.

resize: false

Честно говоря, такого же эффекта можно добиться, если задать родителю просто фиксированный размер. Здесь я не понимаю разработчика — либо я что-то недопонял, либо данная опция имеет место быть в определенных случаях. Подробнее можете посмотреть на примере в Codepen. Попробуйте изменить размер экрана браузера. Потом поменяйте «resize: false» на «resize: true» и поймете о чем идет речь.

initLayout

Данная опция активирует нашу кирпичную сетку при инициализации скрипта. По умолчанию она включена — «initLayout: true». Но можно и отменить.

initLayout: false

Вы можете использовать методы и события перед активацией сетки. Например, вы можете сделать так, что ваша сетка будет активироваться по клику определенной кнопки. Ну и далее что-то в этом роде.

В данной статье я не буду разбирать события и методы, т.к. статья итак получилась объемной. Вы можете их самостоятельно изучить на сайте разработчика. Там же найдете и примеры реализации. Все довольно понятно изложено. Не всегда авторами скриптов пишутся такие инструкции. За инструкцию Masonry разработчику я бы поставил твердую — 5.  🙂

В принципе все то, что я изложил выше хватает, чтобы задействовать кирпичный эффект на своем сайте.

А на этом все. Всем спасибо за внимание. Задавайте вопросы в комментариях, всегда буду рад помочь. Встретимся в следующих статьях. Пока!

Пост был обновлен: Дек 15, 2016

Заур Магомедов
Заур Магомедов

Верстальщик с большим опытом работы. Занимаюсь созданием сайтов с 2009 года. Постоянно обучаюсь и совершенствую свои навыки. Веду свои проекты, в том числе и данный блог.

У меня вы можете:

Оцените пост:

1 балл2 балла3 балла4 балла5 баллов (3 оценок, среднее: 3,33 из 5)
Загрузка...

Проверка орфографии

Система Orphus

20 комментариев к статье "Masonry Layout — кирпичный эффект элементов на сайте. Документация на русском языке"

  • Дима Мар 22, 2017 в 13:52

    Очень интересно! Отличная библиотека, спасибо за наводку!
    Правда приведеные примеры гридов все с одинаковой шириной элементов. Выглядит так, что для этого хватило бы и простого flex-box.
    Было бы интереснее посмотреть на грид с автоматической расстановкой элементов разных размерностей. Примерно как здесь http://codepen.io/anon/pen/rydoyQ

    • Заур Магомедов
      Заур Магомедов Мар 22, 2017 в 13:57

      Есть же примеры и с разной размерностью — примеры на codepen. Вот, например, http://codepen.io/desandro/pen/uwtLs. Перейдите на сайт разработчика, там тоже есть примеры.

  • Aleks Янв 06, 2017 в 12:34

    Добрый день. Подскажите пожалуйста. Например в item есть скрытый блок, и есть кнопочка которая активирует его. По клику на кнопочку активируется блок и увеличивается высота item. по логике остальные item должны подвинуться и дать место для увеличенного блока. Но у меня получается что item увеличился и оказался под другим. А остальные item даже не сдвинулись. Подскажите как решить данную проблему??

    • Заур Магомедов
      Заур Магомедов Янв 06, 2017 в 12:44

      Здравствуйте! Знаете я особо в остальные события и методы не углублялся, но вам примерно нужно следующее — http://masonry.desandro.com/methods.html. Смотрите первый пример и демо — «Layout».

  • Андрей Русов Ноя 29, 2016 в 19:12

    Здравствуйте, как ни извращаюсь, при первой загрузке блога блоки набегают друг на друга. При перезагрузке всё встаёт на свои места. Помогите пожалуйста, как избежать этого? http://gymbalance.ru/blog/

    • Заур Магомедов
      Заур Магомедов Ноя 29, 2016 в 20:25

      ImagesLoaded — начиная с этого места все сделали правильно? Советую еще раз проверить.

  • Александр Авг 24, 2016 в 11:40

    Добрый день.

    Подскажите, а как реализована анимация блоков при загрузке страницы на этом http://dt-europa.ru/uslugi.html примере? У меня анимация происходит только при ресайзе окна.

    • Заур Магомедов
      Заур Магомедов Авг 24, 2016 в 11:52

      Анимацию блоков статей имеете ввиду?

      • Александр Авг 24, 2016 в 11:59

        Да. Они у вас там плавно выстраиваются после загрузки.

        • Заур Магомедов
          Заур Магомедов Авг 24, 2016 в 12:04

          Дополнительных анимаций никаких нет. У вас значит страница быстро загружается поэтому и невидна анимация. Здесь же происходит задержка, вот и все.

          • Александр Авг 24, 2016 в 12:52

            Оказывается, анимация происходит при двойном вызове масонри.

                // initialize Masonry after all images have loaded 
                var $container = $(".grid");
                $container.imagesLoaded( function() {
                    $container.masonry();
                });
                // initialize Masonry
                $(".grid").masonry({
                    columnWidth: ".grid-item",
                    itemSelector: ".grid-item",
                    percentPosition: true
                }); 
            • Заур Магомедов
              Заур Магомедов Авг 24, 2016 в 12:55

              Т.е. у вас двойной вызов был?

              • Александр Авг 24, 2016 в 12:58

                Это ваш код. Отсюда http://dt-europa.ru/uslugi.html
                Я сделал по тому же принципу — сработало.

                • Заур Магомедов
                  Заур Магомедов Авг 24, 2016 в 13:01

                  Может быть, не помню уже. Давно делал сайт.

  • VicKey Июл 11, 2016 в 18:24

    А как все это сделать на WordPress 🙁

    • Заур Магомедов
      Заур Магомедов Июл 11, 2016 в 18:52

      Подключаете в своем шаблоне, ничего сложного нет. Неважно на чем работает у вас сайт. Есть код HTML, CSS, JAVASCRIPT и все. Просто вам надо научиться правильно подключать.

      • VicKey Июл 14, 2016 в 14:38

        Было бы все так просто. 😀 Я только учусь делать темы для WordPress. Сейчас все через функции(functions.php) подключается.

        P.S. Странно, но у вас мой gravatar не подключается

        • Заур Магомедов
          Заур Магомедов Июл 14, 2016 в 14:51

          В functions.php пишется php-код. А в данном случае он вам не нужен.

          На счет gravatar не знаю. Мое фото нормально отображается.

          • VicKey Июл 14, 2016 в 17:52

            Пример вывода скрипта в footer, и что-то там еще:

             
            if ( ! function_exists( 'slug_masonry_init' )) :
            function slug_masonry_exists() { ?>
            
                //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'
                    });
                });
            
            <?php }
            //add to wp_footer
            add_action( 'wp_footer', 'slug_masonry_init' );
            endif; // ! slug_masonry_init exists 
            
            • Заур Магомедов
              Заур Магомедов Июл 14, 2016 в 18:20

              Что вы хотели сказать данным сообщением?

Добавить комментарий

Войти с помощью: 

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Если вы хотите вставить в текст комментария код HTML, CSS, PHP, JavaScript, то обрамите код в соответствии необходимыми тегами:

  • Код HTML - тегами [html] ваш код... [/html]
  • Код CSS - тегами [css] ваш код... [/css]
  • Код PHP - тегами [php] ваш код... [/php]
  • Код JavaScript - тегами [code lang="js"] ваш код... [/code]