플러그인 없이 적용할 수 있는 masonry 레이아웃 방법에 대해 기록
차후 브라우저 지원에 따라, 새롭게 추가된 grid-template-rows:masonry 스펙을 사용할 수 있을 것으로 기대
현재 해당 블로그 내
포트폴리오 페이지에도 적용 중
기존 방법
-
isotope.js, masonry.js 등을 이용한 플러그인 사용
-
각 요소에 position:absolute 준 뒤 JS로 위치 조정
-
Flex box 등으로 레이아웃 지정 (column-count 등으로 사용 가능하나 세로 정렬 됨)
-
grid-auto-rows + grid-row-end 활용 해 위치 조정
이중, 네번째 방법에 대해 기록
요소의 position을 static으로 가져갈 수 있고,
자식 요소의 높이만 감지해 레이아웃을 만듬으로
기존 방식보다, 브라우저 리사이징 시 발생하는 메모리 누수를 최소화
HTML
<div class="masonry-container">
<div class="masonry-item">
<div class="item">1</div>
</div>
<div class="masonry-item">
<div class="item">2</div>
</div>
...
</div>
CSS
.masonry-container {
--gap: 10px;
display: grid;
grid-template-columns: repeat(3, 1fr);
column-gap: var(--gap);
grid-auto-rows: 10px;
}
@media screen and (max-width: 720px) {
.masonry-container {
grid-template-columns: repeat(2, 1fr);
}
}
@media screen and (max-width: 400px) {
.masonry-container {
display: block;
}
.masonry-item {
margin-bottom: var(--gap);
}
}
Javascript
function masonryLayout() {
const masonryContainerStyle = getComputedStyle(
document.querySelector(".masonry-container")
);
const columnGap = parseInt(
masonryContainerStyle.getPropertyValue("column-gap")
);
const autoRows = parseInt(
masonryContainerStyle.getPropertyValue("grid-auto-rows")
);
document.querySelectorAll(".masonry-item").forEach((elt) => {
elt.style.gridRowEnd = `span ${Math.ceil(
elt.querySelector(".item").scrollHeight / autoRows +
columnGap / autoRows
)}`;
});
}
masonryLayout();
window.addEventListener("resize", masonryLayout);