Masonry — это библиотека для создания динамических сеток с плотным расположением элементов, где высота элементов может быть разной. В отличие от стандартного CSS-флоата, Masonry автоматически располагает элементы так, чтобы минимизировать вертикальные пробелы между ними, создавая эффект “кирпичной кладки”.
Для использования Masonry необходимо подключить саму библиотеку и стили для контейнера и элементов сетки:
<link rel="stylesheet" href="styles.css">
<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>
Контейнер сетки должен иметь уникальный класс или идентификатор, а элементы сетки — общий класс.
<div class="grid">
<div class="grid-item">Элемент 1</div>
<div class="grid-item">Элемент 2</div>
<div class="grid-item">Элемент 3</div>
</div>
CSS для сетки и элементов:
.grid {
width: 100%;
}
.grid-item {
width: 200px;
margin-bottom: 16px;
background-color: #ddd;
}
Инициализация выполняется через конструктор Masonry, куда передаются контейнер и параметры конфигурации:
const grid = document.querySelector('.grid');
const masonry = new Masonry(grid, {
itemSelector: '.grid-item',
columnWidth: 200,
gutter: 16,
fitWidth: true
});
Основные параметры:
itemSelector — селектор для элементов сетки.columnWidth — ширина колонки, может быть фиксированной
или вычисляться автоматически.gutter — расстояние между элементами.fitWidth — если true, сетка будет
центрироваться внутри контейнера.Для сеток, где элементы добавляются после загрузки страницы, Masonry
предоставляет методы appended и layout:
const newItem = document.createElement('div');
newItem.classList.add('grid-item');
newItem.textContent = 'Новый элемент';
grid.appendChild(newItem);
masonry.appended(newItem);
masonry.layout();
Метод appended позволяет Masonry корректно расположить
новый элемент без полной переработки сетки. layout можно
вызвать для перерасчёта всех позиций, если размеры элементов
изменились.
Для адаптивных сеток можно использовать процентные значения или медиазапросы в CSS, а Masonry будет автоматически перестраивать колонки при изменении ширины контейнера:
.grid-item {
width: 48%; /* Два элемента в ряд на маленьких экранах */
}
@media (min-width: 768px) {
.grid-item {
width: 23%; /* Четыре элемента в ряд на больших экранах */
}
}
Для динамического изменения размеров можно использовать метод
layout при событии resize:
window.addEventListener('resize', () => {
masonry.layout();
});
В Angular интеграция Masonry требует внимательного подхода, так как работа идет через компонентную архитектуру. Оптимальный способ — создать сервис для управления сеткой и директиву для элементов:
// masonry.service.ts
import { Injectable } from '@angular/core';
import Masonry from 'masonry-layout';
@Injectable({ providedIn: 'root' })
export class MasonryService {
private masonryInstance: Masonry | null = null;
init(gridSelector: string, options: any) {
const grid = document.querySelector(gridSelector) as HTMLElement;
this.masonryInstance = new Masonry(grid, options);
}
layout() {
this.masonryInstance?.layout();
}
appended(element: HTMLElement) {
if (this.masonryInstance) {
this.masonryInstance.appended(element);
this.masonryInstance.layout();
}
}
}
Директива для элементов:
// masonry-item.directive.ts
import { Directive, ElementRef, AfterViewInit } from '@angular/core';
import { MasonryService } from './masonry.service';
@Directive({
selector: '[appMasonryItem]'
})
export class MasonryItemDirective implements AfterViewInit {
constructor(private el: ElementRef, private masonryService: MasonryService) {}
ngAfterViewInit() {
this.masonryService.appended(this.el.nativeElement);
}
}
Компонент с сеткой:
// grid.component.ts
import { Component, AfterViewInit } from '@angular/core';
import { MasonryService } from './masonry.service';
@Component({
selector: 'app-grid',
templateUrl: './grid.component.html',
styleUrls: ['./grid.component.css']
})
export class GridComponent implements AfterViewInit {
constructor(private masonryService: MasonryService) {}
ngAfterViewInit() {
this.masonryService.init('.grid', {
itemSelector: '.grid-item',
columnWidth: 200,
gutter: 16,
fitWidth: true
});
}
}
Masonry предоставляет несколько событий для контроля состояния сетки:
layoutComplete — вызывается после перерасчёта
расположения.removeComplete — после удаления элементов.appendComplete — после добавления новых элементов.Пример подписки на событие:
masonry.on('layoutComplete', (items) => {
console.log('Сетка обновлена', items);
});
layout.imagesLoaded для работы с изображениями,
чтобы Masonry учитывал их размеры:imagesLoaded(grid, () => {
masonry.layout();
});
Masonry хорошо сочетается с библиотеками для ленивой загрузки изображений, анимации и фильтров. Для Angular удобно использовать комбинацию с RxJS для динамического управления потоком данных и Masonry-сеткой.
Masonry обеспечивает гибкую и адаптивную сетку, позволяя создавать визуально привлекательные интерфейсы с минимальными усилиями. В Angular подход с сервисом и директивой делает интеграцию чистой и управляемой через компонентную структуру приложения.