Адаптивная сетка

Packery — это библиотека для создания динамических, «кирпичных» сеток в браузере. Основное отличие Packery от традиционных сеток CSS — автоматическое размещение элементов по доступному пространству, минимизация пустот и возможность создавать нестандартные макеты. Для адаптивного дизайна это особенно важно, так как элементы могут менять размеры или порядок в зависимости от ширины контейнера.

В основе работы лежит контейнер, в котором располагаются элементы. Контейнер должен иметь заданную ширину, а элементы — размеры (ширина, высота) и базовые стили. Packery использует позиционирование с помощью абсолютных координат, поэтому родительский контейнер должен иметь position: relative или position: absolute.

.grid {
  position: relative;
}
.grid-item {
  width: 200px;
  height: 200px;
  margin: 10px;
}
const grid = document.querySelector('.grid');
const pckry = new Packery(grid, {
  itemSelector: '.grid-item',
  gutter: 10
});

Ключевые параметры:

  • itemSelector — CSS-селектор элементов сетки.
  • gutter — промежуток между элементами.
  • percentPosition — если установлено true, Packery использует процентные значения для позиционирования, что критично для адаптивных сеток.
  • columnWidth — фиксированная ширина колонок. Может быть числом или CSS-селектором для элемента-шаблона.

Процентные размеры и адаптивность

Для адаптивной сетки лучше использовать процентные размеры элементов. Это позволяет сетке автоматически подстраиваться под ширину контейнера без необходимости вручную пересчитывать позиции.

.grid-item {
  width: 25%;
  height: auto;
}
const pckry = new Packery('.grid', {
  itemSelector: '.grid-item',
  gutter: '.gutter-sizer',
  percentPosition: true
});

Использование percentPosition: true гарантирует, что Packery корректно позиционирует элементы даже при изменении ширины окна.

Поддержка динамических размеров

Packery умеет перерассчитывать сетку при изменении размеров элементов. Для этого используется метод layout():

pckry.layout();

Если размеры элемента изменяются динамически (например, подгружается изображение или контент), следует использовать imagesLoaded или MutationObserver для вызова перерасчета:

imagesLoaded(grid, function() {
  pckry.layout();
});

Адаптивные точки (breakpoints)

Для реализации адаптивного поведения можно комбинировать Packery с CSS Media Queries. Например, изменять ширину элементов под разные экраны:

.grid-item {
  width: 33.33%;
}

@media (max-width: 768px) {
  .grid-item {
    width: 50%;
  }
}

@media (max-width: 480px) {
  .grid-item {
    width: 100%;
  }
}

После изменения классов или размеров элементов важно вызвать layout():

window.addEventListener('resize', function() {
  pckry.layout();
});

Управление пустотами и порядка элементов

Packery предлагает опции для минимизации пустот и перестановки элементов:

  • fitWidth: true — ширина контейнера подстраивается под количество элементов, предотвращая пустые области справа.
  • originLeft и originTop — позволяют менять направление размещения (например, для RTL-сеток).
const pckry = new Packery('.grid', {
  itemSelector: '.grid-item',
  gutter: 10,
  percentPosition: true,
  fitWidth: true
});

Для динамической перестановки элементов можно использовать метод stamp() для фиксированных элементов и remove() для удаления:

pckry.stamp(document.querySelector('.fixed-item'));
pckry.remove(document.querySelector('.grid-item-to-remove'));
pckry.layout();

Интеграция с анимацией

Packery поддерживает плавные анимации при изменении позиции элементов, используя CSS-трансформации. Для этого достаточно подключить transition к элементам:

.grid-item {
  transition: transform 0.4s ease;
}

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

Использование размеров ячеек (sizer elements)

Для более точной адаптивной сетки можно использовать Sizer Elements — специальные невидимые элементы, задающие размеры колонок или промежутков:

<div class="grid">
  <div class="grid-sizer"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
</div>
const pckry = new Packery('.grid', {
  itemSelector: '.grid-item',
  columnWidth: '.grid-sizer',
  percentPosition: true
});

Это позволяет сетке сохранять пропорции при изменении ширины окна и поддерживать строгий контроль над количеством колонок.

Взаимодействие с другими библиотеками

Packery хорошо интегрируется с:

  • imagesLoaded — для корректного расчета сетки после загрузки изображений.
  • Draggabilly — для перетаскивания элементов внутри сетки.
const draggies = [];
pckry.getItemElements().forEach(itemElem => {
  const draggie = new Draggabilly(itemElem);
  pckry.bindDraggabillyEvents(draggie);
  draggies.push(draggie);
});

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

Оптимизация производительности

Для больших сеток важно учитывать производительность:

  • Использовать percentPosition: true вместо постоянного пересчета в пикселях.
  • Минимизировать количество перерасчетов при изменении размеров окна (debounce resize события).
  • Сокращать количество элементов в DOM, если сетка очень большая, и использовать виртуализацию при необходимости.

Packery сочетает гибкость адаптивной сетки, контроль над расположением элементов и поддержку интерактивности, что делает её мощным инструментом для современных веб-интерфейсов. Адаптивная конфигурация с использованием процентов, sizer элементов и правильного перерасчета позволяет создавать сетки, которые остаются корректными на любом разрешении экрана.