Masonry-раскладка — это красивый способ отображения столбцов с разной высотой, без лишних промежутков между строк. Элементы автоматически распределяются в ряды по высоте, и выглядят как кирпичная кладка.
Стандартный грид-контейнер из четырех колонок можно легко получить с помощью CSS flexbox или CSS grid. Он выглядит примерно так:
Стандартный макет сетки из 4 столбцов с CSS Flexbox
Хотя в этом подходе нет ничего плохого, как видно на изображении выше, при наличии динамического контента могут возникать большие промежутки. Существует несколько способов борьбы с избыточным пространством — ограничивать количество слов или делать столбцы одинаковой высоты.
В этом уроке я вам покажу другой подход. Он называется кирпичной кладкой или плиточной раскладкой (masonry layout). Он широко используется для галерей изображений, поскольку в большинстве случаев изображения не могут быть ограничены так же, как и текст. Если бы мы взяли тот же пример, что и выше, Masonry-раскладка выглядела бы примерно так:
4-колонная кирпичная кладка
Как видно на изображении, большие промежутки теперь изящно обработаны. Существует множество учебников в интернете о создании masonry-раскладки, но они либо рекомендуют использовать дорогие сторонние библиотеки JavaScript с избыточным кодом, либо утверждают, что Masonry-эффект можно достичь с помощью чистого CSS (без JavaScript). Хоть, теоретически, Masonry-раскладку можно создать и без JavaScript, существуют несколько важных ограничений, которые постоянно мешают ей работать! Первый метод, основанный только на CSS, использует CSS grid и работает путем нацеливания на разные дочерние элементы. Это может сработать со статическим контентом, но если вы не знаете количество элементов в сетке, у вас могут возникнуть проблемы. Есть также способ создания masonry-раскладки с помощью CSS-grid или flexbox, но это изменяет порядок элементов. Несмотря на то, что этот способ подходит для галерей изображений, где порядок самих изображений не так важен, в ситуациях, где мы хотим отобразить последние сообщения в Masonry-раскладке, этот подход не сработает. Кроме того, ради справедливости стоит отметить, что в Firefox существует новое экспериментальное свойство, которое, наконец, приводит все элементы к работе… за исключением того, что это свойство до сих пор не поддерживается в основных браузерах, за исключением Firefox, и вам необходимо включить экспериментальные функции вашего браузера, чтобы увидеть его в действии. Вся эта информация подразумевает, что в настоящее время мы застряли с использованием JavaScript для достижения masonry-раскладки. Практически все уроки в интернете советуют использовать JS библиотеки для ее достижения. Однако это совершенно не обязательно, так как вы можете постичь красивую masonry-раскладку всего несколькими строками JavaScript. Вот как это сделать:
Создание плиточной раскладки с использованием CSS и только Vanilla JS
The HTML Markup
<div class="post-container">
<div class="post-inner">
<!--You Need a List of Articles Here-->
<article class="post hentry">
Article One
</article>
</div>
</div>
Мы будем использовать вышеуказанную разметку HTML. Вы можете использовать любые классы, которые вам нравятся, но важно, чтобы элементы asonry-раскладки были обернуты в контейнер (в нашем случае это div с классом «post-inner»). Также нам понадобится дополнительная оболочка, чтобы всё сработало (здесь она называется «post-container»).
CSS
Наш CSS-код позволяет создавать многоколоночный макет:
@media (min-width: 54rem) {
.masonry-layout {
box-sizing: border-box;
--columns: 1;
--gap: 2rem;
display: grid;
grid-template-columns: repeat(var(--columns), 1fr);
grid-gap: var(--gap);
padding: 2rem;
}
.masonry-layout > div > img,
.masonry-layout > div > div {
width: 100%;
margin-bottom: 2rem;
}
.masonry-layout.columns-1 {
--columns: 1;
}
.masonry-layout.columns-2 {
--columns: 2;
}
.masonry-layout.columns-3 {
--columns: 3;
}
.masonry-layout.columns-4 {
--columns: 4;
}
}
Не изменяйте здесь этот CSS, он вам понадобится для работы js-кода, который мы собираемся добавить.
JS
Вот JavaScript-код, который мы будем использовать.
const fecthMasonry = function( container, items, columns ) {
const containerElement = document.getElementsByClassName( container )[ 0 ] || '';
if ( ! containerElement ) {
return;
}
const wrapperElement = containerElement.parentNode;
const masonryElements = document.querySelectorAll( '.' + items );
containerElement.parentNode.removeChild( containerElement );
const newElement = document.createElement( 'div' );
newElement.setAttribute( 'id', container );
newElement.classList.add( 'masonry-layout', 'columns-' + columns );
wrapperElement.appendChild( newElement );
let countColumn = 1;
for ( let i = 1; i <= columns; i++ ) {
const newColumn = document.createElement( 'div' );
newColumn.classList.add( 'masonry-column-' + i );
newElement.appendChild( newColumn );
}
for ( let i = 0; i < masonryElements.length; i++ ) {
const col = document.querySelector( '#' + container + ' > .masonry-column-' + countColumn );
col.appendChild( masonryElements[ i ] );
countColumn = countColumn < columns ? countColumn + 1 : 1;
}
};
/* Pass data to generate masonry layout */
fecthMasonry( 'framework-post-inner', 'post', 4 );
Первая функция fetchMasonry — вспомогательная, которая получает данные, необходимые для создания masonry-раскладки. Именно здесь происходит волшебство, и вам не нужно ничего менять. Вторая функция — это место, где вы указываете, какие DOM-элементы отображать в Masonry-раскладке. Мы передаем три параметра. Первый — имя класса родительского элемента. В нашем случае это framework-post-inner. Второй параметр — класс элементов внутри Masonry-раскладки. Финальный параметр — сколько столбцов вы хотите иметь. Вы можете выбрать от 2 до 4.
Вот и все! Если вам понравилась эта статья, поделитесь ею, ну а я желаю вам удачи в вашем следующем проекте!