Библиотека Muuri работает поверх обычной DOM-разметки и не требует специфических HTML-тегов. Однако корректная работа сетки зависит от правильной структуры контейнера и элементов. Muuri управляет позиционированием элементов с помощью JavaScript и CSS-трансформаций, поэтому ключевое требование — наличие контейнера и вложенных элементов-ячеек.
Минимальная структура выглядит следующим образом:
<div class="grid">
<div class="item">
<div class="item-content">...</div>
</div>
<div class="item">
<div class="item-content">...</div>
</div>
<div class="item">
<div class="item-content">...</div>
</div>
</div>
Здесь присутствуют три уровня:
Каждый уровень выполняет отдельную функцию в механизме работы Muuri.
Контейнер — это DOM-элемент, внутри которого располагаются элементы сетки. Именно он передаётся в конструктор Muuri при создании экземпляра.
const grid = new Muuri('.grid');
Контейнер выполняет несколько задач:
Если Muuri инициализируется до появления контейнера в DOM, библиотека не сможет построить сетку.
relative или static.На практике чаще используется:
.grid {
position: relative;
}
Muuri использует абсолютное позиционирование элементов внутри контейнера, поэтому наличие контекста позиционирования предотвращает смещение элементов относительно страницы.
Если контейнер скрыт (display: none), библиотека не
сможет вычислить размеры элементов. Это приводит к неправильной
раскладке.
Элемент сетки — это непосредственный объект управления Muuri. Каждый такой элемент рассматривается библиотекой как отдельный блок, который можно:
Минимальный пример элемента:
<div class="item">
<div class="item-content">
Контент
</div>
</div>
Muuri работает именно с внешним элементом .item.
1. Элемент должен быть прямым потомком контейнера
Нельзя размещать элементы через дополнительные обёртки:
Неправильно:
<div class="grid">
<div class="wrapper">
<div class="item"></div>
</div>
</div>
Правильно:
<div class="grid">
<div class="item"></div>
</div>
Muuri определяет элементы через querySelectorAll внутри
контейнера и рассчитывает их координаты исходя из прямого вложения.
2. Элемент должен иметь фиксируемые размеры
Muuri вычисляет размеры элемента при построении сетки. Размеры могут задаваться разными способами:
Пример:
.item {
width: 200px;
height: 150px;
}
или
.item {
width: 25%;
}
При использовании адаптивных размеров Muuri пересчитывает расположение элементов при изменении размеров контейнера.
3. Элемент не должен иметь абсолютное позиционирование
Muuri самостоятельно управляет позиционированием элементов. Если задать:
.item {
position: absolute;
}
это приведёт к конфликту логики.
Библиотека автоматически применяет позиционирование к элементам.
Muuri рекомендует использовать дополнительный внутренний элемент — контейнер содержимого.
<div class="item">
<div class="item-content">
...
</div>
</div>
Этот слой необходим для нескольких задач:
Muuri перемещает внешний элемент .item с помощью
CSS-трансформаций:
transform: translate(...)
Если контент напрямую расположен внутри .item, при
анимации могут возникать проблемы:
Внутренний контейнер .item-content остаётся стабильным,
а .item выступает только оболочкой.
Типичная базовая конфигурация выглядит следующим образом:
.grid {
position: relative;
}
.item {
width: 200px;
}
.item-content {
position: relative;
width: 100%;
height: 100%;
}
Такой набор обеспечивает:
Muuri хорошо работает с адаптивной разметкой. Ширина элементов может задаваться в процентах.
Пример:
.item {
width: 25%;
}
При изменении ширины контейнера сетка автоматически перестраивается.
Внутреннее содержимое может иметь собственную адаптивную структуру:
<div class="item">
<div class="item-content">
<img src="image.jpg">
</div>
</div>
Если изображения влияют на высоту элементов, необходимо учитывать момент их загрузки.
Частая проблема — инициализация сетки до загрузки изображений.
Если Muuri вычислит размеры элементов до загрузки картинок, высота элементов изменится позже, что нарушит сетку.
Структура:
<div class="item">
<div class="item-content">
<img src="photo.jpg">
</div>
</div>
Решение — инициализация после загрузки изображений.
Используется библиотека imagesLoaded:
imagesLoaded('.grid', function () {
const grid = new Muuri('.grid');
});
Это гарантирует, что размеры элементов уже окончательные.
Полный базовый пример разметки:
<div class="grid">
<div class="item">
<div class="item-content">
Карточка 1
</div>
</div>
<div class="item">
<div class="item-content">
Карточка 2
</div>
</div>
<div class="item">
<div class="item-content">
Карточка 3
</div>
</div>
</div>
Инициализация:
const grid = new Muuri('.grid');
CSS:
.grid {
position: relative;
}
.item {
width: 200px;
}
.item-content {
background: #eee;
padding: 20px;
}
Muuri позволяет использовать HTML-атрибуты для хранения данных.
Например:
<div class="item" data-category="news">
<div class="item-content">
...
</div>
</div>
Такие атрибуты часто используются для:
Muuri не накладывает ограничений на использование пользовательских атрибутов.
Элементы можно изначально скрывать:
<div class="item hidden">
<div class="item-content"></div>
</div>
CSS:
.hidden {
display: none;
}
Muuri автоматически игнорирует элементы с display: none
при построении сетки.
Для динамического управления видимостью используется API библиотеки.
Muuri поддерживает элементы различной высоты и ширины.
Пример:
.item.small {
width: 200px;
height: 150px;
}
.item.large {
width: 400px;
height: 300px;
}
Разметка:
<div class="grid">
<div class="item small">
<div class="item-content"></div>
</div>
<div class="item large">
<div class="item-content"></div>
</div>
</div>
Алгоритм раскладки автоматически размещает элементы наиболее оптимальным образом.
Неправильно:
<div class="item">
Контент
</div>
Правильно:
<div class="item">
<div class="item-content">
Контент
</div>
</div>
Неправильно:
<div class="grid">
<section>
<div class="item"></div>
</section>
</div>
Правильно:
<div class="grid">
<div class="item"></div>
</div>
Ошибка:
const grid = new Muuri('.grid');
если внутри элементов загружаются изображения.
Это приводит к:
Правильная структура разметки влияет не только на корректность отображения, но и на производительность.
Muuri выполняет:
Избыточная вложенность DOM увеличивает нагрузку на браузер.
Рекомендуется:
.itemДля сложных карточек интерфейса обычно используется следующая структура:
<div class="item">
<div class="item-content">
<div class="card">
<div class="card-header"></div>
<div class="card-body"></div>
<div class="card-footer"></div>
</div>
</div>
</div>
Muuri управляет только .item, остальная структура
остаётся полностью свободной.
Это позволяет строить:
без изменения принципов работы сетки.