Изменение количества колонок

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


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

Isotope не использует прямое задание количества колонок через параметр. Количество колонок определяется шириной контейнера и шириной элементов. При этом важными понятиями являются:

  • itemSelector — CSS-селектор элементов сетки.
  • percentPosition — параметр, указывающий, что позиции элементов задаются в процентах относительно контейнера.
  • masonry — режим компоновки, который позволяет автоматически располагать элементы по колонкам, заполняя пустые пространства.

Пример базовой инициализации:

var iso = new Isotope('.grid', {
  itemSelector: '.grid-item',
  layoutMode: 'masonry',
  percentPosition: true,
  masonry: {
    columnWidth: '.grid-sizer'
  }
});

Здесь .grid-sizer — это невидимый элемент-сетка, который задаёт ширину колонки. Именно изменение его размеров напрямую влияет на количество колонок.


Управление шириной колонок

Количество колонок определяется формулой:

количество колонок ≈ ширина контейнера / ширина колонки

Для реализации адаптивной сетки часто используют медиазапросы или вычисление ширины через Jav * aScript:

function updateColumnWidth() {
  var containerWidth = document.querySelector('.grid').offsetWidth;
  var columns;

  if (containerWidth > 1200) {
    columns = 4;
  } else if (containerWidth > 800) {
    columns = 3;
  } else if (containerWidth > 500) {
    columns = 2;
  } else {
    columns = 1;
  }

  var columnWidth = containerWidth / columns;
  document.querySelector('.grid-sizer').style.width = columnWidth + 'px';

  iso.layout(); // Перерасчёт сетки после изменения ширины колонки
}

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

Ключевой момент: после изменения ширины колонки необходимо вызвать метод layout(), чтобы Isotope пересчитал расположение элементов.


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

Если вместо фиксированной ширины использовать процентные значения, сетка автоматически адаптируется:

.grid-sizer {
  width: 25%; /* 4 колонки */
}

.grid-item {
  width: 25%; /* соответствует ширине колонки */
}

При изменении ширины контейнера количество видимых колонок автоматически меняется без необходимости переписывать JavaScript. Этот подход идеально подходит для responsive-дизайна.


Динамическое изменение количества колонок

Иногда требуется динамически изменять количество колонок на основе условий интерфейса или пользовательских действий. Для этого можно изменять ширину .grid-sizer через JS и пересчитывать сетку:

function setColumns(columns) {
  var container = document.querySelector('.grid');
  var columnWidth = container.offsetWidth / columns;
  document.querySelector('.grid-sizer').style.width = columnWidth + 'px';
  iso.layout();
}

// Пример: переключение между 2 и 4 колонками
document.querySelector('#toggleColumns').addEventListener('click', function() {
  var currentColumns = document.querySelector('.grid-sizer').offsetWidth > 200 ? 2 : 4;
  setColumns(currentColumns);
});

Важно: Isotope всегда ориентируется на текущую ширину .grid-sizer. Поэтому для корректного пересчета сетки необходимо правильно рассчитывать ширину колонок в пикселях или процентах.


Интеграция с CSS Grid и Flexbox

Isotope можно сочетать с современными CSS-технологиями:

  • CSS Grid — для предсказуемой разметки элементов, где .grid-sizer задаёт минимальную ширину колонки.
  • Flexbox — для элементов с динамической шириной, при этом Isotope будет управлять позиционированием элементов по вертикали и горизонтали.

Пример с CSS Grid:

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-gap: 10px;
}

В этом случае .grid-sizer может быть использован для определения минимальной ширины, а Isotope управляет фильтрацией и анимацией.


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

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

  • Минимизировать количество вызовов layout() — вызывать его только после завершения всех изменений.
  • Использовать imagesLoaded, чтобы сетка правильно считала высоту изображений и корректно располагала элементы.
  • Кешировать размеры контейнера, чтобы не пересчитывать их на каждом событии resize.
imagesLoaded('.grid', function() {
  iso.layout();
});

Это предотвращает “прыжки” элементов при загрузке изображений и изменении количества колонок.