Media queries и breakpoints

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


Основные концепции

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

Media query — стандартный CSS-инструмент, который позволяет применять определённые стили в зависимости от характеристик устройства (ширина, высота, ориентация и т.д.). В Muuri media queries могут быть использованы совместно с JavaScript для изменения конфигурации сетки на лету.


Настройка breakpoints в Muuri

Muuri не имеет встроенной поддержки CSS-style breakpoints, поэтому адаптивность реализуется через JavaScript. Основная логика строится на прослушивании события resize и изменении параметров сетки:

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

function updateGridColumns() {
  const width = window.innerWidth;
  let columns;

  if (width < 600) {
    columns = 1;
  } else if (width < 900) {
    columns = 2;
  } else {
    columns = 4;
  }

  grid.getItems().forEach(item => {
    item.getElement().style.width = `${100 / columns}%`;
  });

  grid.refreshItems().layout();
}

window.addEventListener('resize', updateGridColumns);
updateGridColumns();

Ключевые моменты:

  • window.innerWidth используется для определения текущей ширины экрана.
  • Изменение ширины элементов (item.getElement().style.width) позволяет сетке перестраиваться без потери данных.
  • grid.refreshItems().layout() обновляет расположение элементов в сетке после изменения стилей.

Использование CSS media queries совместно с Muuri

Иногда удобнее использовать CSS для базовой адаптивности, а Muuri — для динамической подстройки сетки. Например, можно задать классы для разных размеров экрана:

.grid-item {
  width: 100%;
}

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

@media (min-width: 900px) {
  .grid-item {
    width: 25%;
  }
}

В этом случае Muuri будет корректно работать, так как элементы уже имеют нужную ширину, а сетка просто перестроится:

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

window.addEventListener('resize', () => grid.layout());

Преимущества такого подхода:

  • CSS управляет базовой адаптивностью.
  • JavaScript обеспечивает точное выравнивание и анимацию сетки.
  • Нет необходимости вручную вычислять количество колонок в JS.

Динамическое изменение конфигурации Muuri через breakpoints

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

function updateGridSettings() {
  const width = window.innerWidth;

  if (width < 600) {
    grid.filter(item => item.getElement().dataset.type === 'mobile');
  } else if (width < 900) {
    grid.filter(item => item.getElement().dataset.type !== 'desktop');
  } else {
    grid.show(grid.getItems());
  }

  grid.layout();
}

window.addEventListener('resize', updateGridSettings);
updateGridSettings();

Особенности:

  • Метод grid.filter() позволяет динамически скрывать или показывать элементы.
  • grid.show() возвращает все элементы в сетку.
  • grid.layout() пересчитывает положение элементов после изменения конфигурации.

Рекомендации по проектированию адаптивных сеток

  1. Определить ключевые точки разрыва (breakpoints) на основе контента, а не только устройства.
  2. Использовать сочетание CSS и JS: CSS для базовой адаптивности, JS для динамики.
  3. Избегать слишком частого обновления сетки: добавление debounce для события resize улучшает производительность.
  4. Разделять логику размеров и фильтров: это упрощает поддержку сетки и добавление новых правил адаптивности.

Пример debounce для оптимизации resize

function debounce(fn, delay) {
  let timer;
  return function() {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, arguments), delay);
  };
}

window.addEventListener('resize', debounce(updateGridColumns, 100));

Эффект:

  • Событие resize не вызывает лишних пересчётов сетки.
  • Сетка остается отзывчивой, но производительность сохраняется даже на больших страницах.

Использование media queries и breakpoints в Muuri позволяет создавать сетки, которые плавно адаптируются под любое устройство, сохраняя порядок, анимации и удобство управления контентом.