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

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

Адаптивная верстка в контексте Muuri строится на нескольких принципах:

  • Динамическая перестройка сетки при изменении размеров контейнера.
  • Автоматическое выравнивание элементов по заданным критериям (ширина, высота, порядок).
  • Поддержка сортировки и фильтрации с сохранением адаптивности.

Инициализация сетки с адаптивной логикой

Создание сетки Muuri начинается с простого объявления контейнера и элементов:

const grid = new Muuri('.grid', {
  dragEnabled: true,
  layout: {
    fillGaps: true,
    rounding: false
  },
  layoutOnResize: true,
  layoutOnInit: true
});

Ключевые параметры для адаптивности:

  • layoutOnResize – автоматически перестраивает сетку при изменении размера контейнера.
  • fillGaps – оптимизирует размещение элементов, заполняя пустоты в сетке при изменении размеров.
  • rounding – управление округлением координат для плавной анимации.

Управление размерами элементов

Адаптивность Muuri во многом зависит от правильного управления размерами элементов. Существует несколько подходов:

Процентные размеры

.grid-item {
  width: 25%;
  box-sizing: border-box;
}

Такой подход позволяет сетке автоматически перестраиваться при изменении ширины контейнера. В сочетании с layoutOnResize элементы будут равномерно распределяться по рядам.

Минимальные и максимальные размеры

.grid-item {
  min-width: 150px;
  max-width: 300px;
  flex-grow: 1;
}

Использование min-width и max-width предотвращает чрезмерное сжатие или растяжение элементов на малых и больших экранах.

Применение item.show() и item.hide()

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

window.addEventListener('resize', () => {
  grid.getItems().forEach(item => {
    if (window.innerWidth < 768) {
      item.hide();
    } else {
      item.show();
    }
  });
});

Медиа-запросы и Muuri

Muuri интегрируется с CSS-медиа-запросами для точного контроля адаптивности:

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

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

В этом случае Muuri автоматически пересчитает расположение элементов благодаря layoutOnResize.


Фильтрация и сортировка в адаптивной сетке

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

document.querySelector('#filter-button').addEventListener('click', () => {
  grid.filter(item => item.getElement().classList.contains('active'));
});

Сортировка элементов:

grid.sort((a, b) => a.getElement().dataset.order - b.getElement().dataset.order);

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


Реакция на динамическое добавление и удаление элементов

Адаптивная верстка требует обработки динамически добавляемых элементов. Muuri предоставляет методы:

// Добавление элемента
const newItem = document.createElement('div');
newItem.className = 'grid-item';
grid.add(newItem);

// Удаление элемента
grid.remove(grid.getItemsByElement(elementToRemove), { removeElements: true });

Каждое добавление или удаление автоматически запускает перерасчет сетки, что обеспечивает плавную адаптацию к изменениям контента.


Использование кастомной функции layout для адаптивности

Muuri позволяет определять собственные алгоритмы размещения элементов:

const grid = new Muuri('.grid', {
  layout: {
    fillGaps: true,
    horizontal: false,
    alignRight: false,
    alignBottom: true
  }
});

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


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

При большом количестве элементов или частых изменениях размеров важно минимизировать перерасчеты:

  • Использовать layout(false) для временной блокировки перерасчета при массовых изменениях.
  • Группировать добавления/удаления элементов и вызывать grid.refreshItems().layout() один раз после всех изменений.
  • Отслеживать события resize через debounce, чтобы не вызывать перерасчет сетки слишком часто.
let resizeTimer;
window.addEventListener('resize', () => {
  clearTimeout(resizeTimer);
  resizeTimer = setTimeout(() => grid.refreshItems().layout(), 200);
});

Итоговые рекомендации по адаптивной верстке с Muuri

  1. Всегда включать layoutOnResize и использовать гибкие размеры элементов.
  2. Применять медиазапросы и процентные размеры для различных экранов.
  3. Использовать встроенные методы фильтрации и сортировки для сохранения адаптивности.
  4. Управлять динамическим добавлением и удалением элементов через add, remove и refreshItems.
  5. Оптимизировать производительность при изменении размеров и больших сетках через debounce и групповые операции.

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