Packery — это библиотека для динамического расположения элементов в сетке с произвольными размерами, обеспечивающая минимизацию пустого пространства. В отличие от стандартных грид-систем, Packery работает по принципу «bin-packing», то есть максимально эффективно упаковывает элементы в доступное пространство, учитывая их размеры и порядок.
Базовое использование требует подключения библиотеки и инициализации контейнера:
const grid = document.querySelector('.grid');
const pckry = new Packery(grid, {
itemSelector: '.grid-item',
gutter: 10
});
Packery автоматически вычисляет оптимальное расположение элементов и распределяет их по строкам и колонкам с учётом пробелов.
Основная сила Packery заключается в умном заполнении пустых мест. Если в сетке появляются элементы разной высоты или ширины, стандартные сетки оставляют пустые области. Packery минимизирует эти зоны:
Пример добавления элемента и динамического заполнения пустого места:
const newItem = document.createElement('div');
newItem.className = 'grid-item';
grid.appendChild(newItem);
pckry.appended(newItem);
pckry.layout();
Метод appended сообщает Packery о новом элементе, после
чего layout перераспределяет все элементы.
Packery позволяет работать с элементами произвольных размеров, благодаря чему достигается эффект «мозаики». Чтобы добиться корректного заполнения:
.grid-item {
width: 100px;
height: 100px;
}
.grid-item.wide {
width: 210px;
}
.grid-item.tall {
height: 210px;
}
stamp для
закрепления определённых элементов в сетке:pckry.stamp(document.querySelector('.grid-item.stamp'));
pckry.layout();
Элемент, отмеченный stamp, не будет перемещаться, а
остальные будут подстраиваться вокруг него, заполняя пустые области.
Packery поддерживает добавление, удаление и перемещение элементов без потери согласованности расположения. Методы для динамических изменений:
appended(elements) — добавляет новые элементы.removed(elements) — удаляет элементы из сетки.prepended(elements) — вставляет элементы в начало
контейнера.layout() — принудительно пересчитывает расположение
всех элементов.Пример удаления элемента:
const item = document.querySelector('.grid-item');
pckry.remove(item);
pckry.layout();
Для точной настройки заполнения пробелов можно использовать:
const pckry = new Packery(grid, {
itemSelector: '.grid-item',
gutter: 10,
columnWidth: 120
});
const pckry = new Packery(grid, {
itemSelector: '.grid-item',
gutter: 10,
percentPosition: true
});
Эти параметры помогают минимизировать неиспользуемое пространство при изменении размеров окна или элементов.
Packery часто используют совместно с Draggabilly для реализации перетаскивания элементов. Пример:
const draggies = [];
pckry.getItemElements().forEach(itemElem => {
const draggie = new Draggabilly(itemElem);
pckry.bindDraggabillyEvents(draggie);
draggies.push(draggie);
});
В результате элементы можно перемещать вручную, а Packery будет автоматически перераспределять их для плотного заполнения.
Для больших сеток рекомендуется:
imagesLoaded, чтобы
убедиться, что размеры изображений известны перед вызовом
layout().layout() при массовых изменениях,
группируя добавления/удаления.Пример с imagesLoaded:
imagesLoaded(grid, function() {
pckry.layout();
});
gutter и columnWidth для
согласованной структуры.stamp.appended() и
layout().Эти приёмы позволяют создавать адаптивные, плотные и визуально аккуратные сетки с минимальными пустыми зонами.