Masonry — это библиотека для создания сеток с динамическим расположением элементов, часто называемая «Pinterest-style grid». Для использования в Vanilla JavaScript подключение может осуществляться несколькими способами:
<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>
npm install masonry-layout
и импорт в проекте:
import Masonry from 'masonry-layout';
После подключения Masonry можно приступать к созданию сетки.
При инициализации Masonry создается объект с набором конфигурационных опций:
const grid = document.querySelector('.grid');
const msnry = new Masonry(grid, {
itemSelector: '.grid-item',
columnWidth: 200,
gutter: 10,
fitWidth: true,
percentPosition: true,
horizontalOrder: false
});
Описание ключевых параметров:
true, сетка
центрируется внутри родителя.true, Masonry
использует процентные размеры для более гибкого отклика на изменение
ширины контейнера.true, элементы
будут располагаться по горизонтали, иначе по вертикали.Masonry предоставляет методы для динамического управления сеткой:
msnry.layout();
const newItem = document.createElement('div');
newItem.classList.add('grid-item');
grid.appendChild(newItem);
msnry.appended(newItem);
prepended(elements) – добавляет элементы в начало сетки.
remove(elements) – удаляет элементы из Masonry:
msnry.remove(document.querySelectorAll('.grid-item.remove'));
msnry.layout();
msnry.destroy();
Для динамического контента, например, при подгрузке изображений,
важно учитывать момент их загрузки, иначе Masonry рассчитает позиции
некорректно. Используется событие imagesLoaded:
imagesLoaded(grid, function() {
msnry.layout();
});
Пошаговая логика:
layout() для
корректного распределения элементов.Это особенно важно при работе с изображениями разного размера, поскольку Masonry рассчитывает позиции на основе реальной высоты элементов.
Для адаптивной верстки рекомендуется использовать процентные размеры
колонок и свойство percentPosition: true:
const msnry = new Masonry(grid, {
itemSelector: '.grid-item',
columnWidth: '.grid-sizer',
percentPosition: true
});
.grid-sizer служит базовой единицей сетки..grid-item будут подстраиваться под размер
.grid-sizer.Такой подход позволяет Masonry корректно перестраиваться при изменении ширины окна браузера.
Masonry поддерживает несколько событий, которые полезны для интеграции с пользовательским интерфейсом:
msnry.on('layoutComplete', function(items) {
console.log('Сетка обновлена, элементов:', items.length);
});
Минимизировать количество пересчетов: вызов
layout() после каждой мелкой операции может замедлять
страницу. Лучше использовать пакетное добавление через
appended() или prepended().
Использовать CSS-анимации с осторожностью:
Masonry меняет transform для элементов, поэтому анимации
высоты и позиционирования могут конфликтовать.
Предварительная установка размеров элементов: если известно точное соотношение ширины и высоты, сетка будет рендериться быстрее и без визуальных «скачков».
Пример совместного использования:
const msnry = new Masonry(grid, { itemSelector: '.grid-item', columnWidth: 200 });
const draggies = [];
grid.querySelectorAll('.grid-item').forEach(item => {
const draggie = new Draggabilly(item);
draggies.push(draggie);
draggie.on('dragEnd', () => msnry.layout());
});
<div class="grid">
<div class="grid-sizer"></div>
<div class="grid-item">Элемент 1</div>
<div class="grid-item">Элемент 2</div>
<div class="grid-item">Элемент 3</div>
</div>
.grid — контейнер Masonry..grid-sizer — базовый размер колонки..grid-item — элементы сетки.Такой подход упрощает адаптивность и оптимизирует работу Masonry.
layout().layout().Пример фильтрации:
document.querySelectorAll('.filter-btn').forEach(btn => {
btn.addEventListener('click', () => {
const filter = btn.dataset.filter;
grid.querySelectorAll('.grid-item').forEach(item => {
item.style.display = item.classList.contains(filter) ? 'block' : 'none';
});
msnry.layout();
});
});
Эта система позволяет создавать высокоэффективные, визуально привлекательные сетки для сайтов с динамическим контентом, поддерживая адаптивность, анимацию и интеграцию с другими инструментами Vanilla JavaScript.