메이슨리

Masonry

벽돌을 쌓듯, 높이가 제각각인 카드를 빈틈없이 채워 넣는 다단 레이아웃. Pinterest가 대표 사례입니다.

다른 이름: Pinterest layoutBrick layout
···
html
<div class="wall" id="wall"></div>
css
.wall{width:min(94%,560px);height:min(90%,340px);columns:3;column-gap:clamp(5px,1.4vmin,10px)}
.brick{break-inside:avoid;margin-bottom:clamp(5px,1.4vmin,10px);border-radius:8px;background:var(--surface);
  border:1px solid var(--line);box-shadow:0 1px 6px rgba(0,0,0,.06);transition:height .6s cubic-bezier(.2,.8,.2,1)}
.brick:nth-child(3n+1){background:color-mix(in oklab,var(--accent) 22%,var(--surface))}
.brick:nth-child(3n+2){background:color-mix(in oklab,var(--accent-3) 22%,var(--surface))}
js
const wall = document.getElementById('wall');
const heights = [46, 88, 64, 112, 54, 96, 70, 120, 58];
for (let i = 0; i < heights.length; i++) {
  const d = document.createElement('div');
  d.className = 'brick';
  d.style.height = heights[i] + 'px';
  wall.appendChild(d);
}
const bricks = () => wall.querySelectorAll('.brick');
setInterval(() => {
  const list = bricks();
  const target = list[Math.floor(Math.random() * list.length)];
  target.style.height = (40 + Math.floor(Math.random() * 100)) + 'px';
}, 900);

일반 그리드는 모든 칸의 높이를 맞추기 때문에 세로로 긴 이미지 밑에 빈 공간이 남습니다. 메이슨리는 각 열이 독립적으로 다음 항목을 "가장 짧은 열"에 채워 넣어서 그 빈 공간을 없앱니다.

CSS만으로는 `columns: 3`(다단 레이아웃)으로 비슷하게 흉내 낼 수 있지만, 이 경우 항목이 위→아래로 한 열을 다 채운 뒤 다음 열로 넘어가서 읽는 순서가 Z가 아니라 세로로 꺾입니다. 진짜 Pinterest 식 순서(왼쪽부터 가장 짧은 열에 채우기)는 JS로 각 열의 높이를 추적하거나, 최근 CSS Grid의 `grid-template-rows: masonry`(현재 Firefox만 지원)가 필요합니다.

카드 수가 적으면 그냥 균일한 그리드로도 충분합니다. 메이슨리는 콘텐츠 높이가 정말 들쭉날쭉하고 수량이 많을 때(이미지 피드, 핀 모음) 빛을 발합니다.

언제 쓰나

이미지·카드 높이가 제각각이고 개수가 많을 때. 순서가 중요한 콘텐츠(단계별 안내 등)에는 쓰지 마세요 — 채우는 순서가 시각적 순서와 어긋납니다.