CSS로 메이슨리 스타일 목록 만들기

<div class="container">
    <div class="item"><img src="./1.jpg"/></div>
    <div class="item"><img src="./2.jpg"/></div>
    <div class="item"><img src="./3.jpg"/></div>
    <div class="item"><img src="./4.jpg"/></div>
    <div class="item"><img src="./5.jpg"/></div>
    <div class="item"><img src="./6.jpg"/></div>
    <div class="item"><img src="./7.jpg"/></div>
    <div class="item"><img src="./8.jpg"/></div>
    <div class="item"><img src="./9.jpg"/></div>
</div>

이미지는 너비가 모두 300px입니다.

CSS가 없으면 블록 태그는 세로로 한 줄로 나열됩니다.

CSS로 메이슨리 레이아웃과 같은 모양을 만들기 위해서는 컬럼 모드를 활용합니다.

컬럼 모드는 웹 페이지를 2개 이상의 컬럼으로 나누어서 컬럼 흐름을 따라서 컨텐츠가 배치되도록 하는 것입니다.

컬럼 모드는 "column-count"와 "column-gap" 2개의 속성으로 컬럼 갯수와 사이 여백을 정의합니다.

먼저 "container" 클래스에 컬럼 모드를 정의합니다.

배치할 이미지 아이템들 하단에 마진을 20px 지정해서 간격을 띄워주고, 이미지가 컬럼 너비를 넘지 않도록 이미지 너비를 "100%"해서 컬럼 너비에 맞도록 해줍니다.

.container {
    width: 750px; /* 전체 너비 */
    margin: 0 auto; /* 가운데 정렬 */
    column-count: 3; /* 컬럼 갯수 */
    column-gap: 20px; /* 컬럼 사이 여백 */
}
.item {
    margin: 0 0 20px 0; /* 아이템 하단 여백 */
}
.item img{
    width: 100%; /* 이미지 너비 맞춤 */
}

아이템 배치가 되고 나면 다음처럼 컬럼을 기준으로 적절하게 이미지들이 배치가 됩니다.

컬럼 모드로 메이슨리 처럼 이미지를 배치

여기까지 완성되었으면 90%는 끝난 것입니다.

나머지는 장식적인 요소와 배치 상의 문제를 피하는 속성을 추가하는 것입니다.

아이템 테두리를 둥글게 다듬고 그림자 효과를 추가해서 조금 더 보기 좋게 만듭니다.

.item {
    margin: 0 0 20px 0;
    line-height: 0;
    width: 100%;
    border-radius: 20px; /* 테두리 둥글게 */
    overflow: hidden; /* 둥근 테두리 바깥으로 이미지 삐져나오지 않게 감춤 */
    box-shadow: 0 8px 20px -15px #000; /* 그림자 효과 */
}

디자인 요소를 입힌 메이슨리 스타일 목록

컬럼 개수와 아이템 너비를 관리하기 편하도록 변수를 선언해서 자동으로 전체 너비까지 계산되도록 컨테이너 클래스를 조금 수정합니다.

:root {
    --item-width: 250px; /* 아이템 너비 */
    --column-count : 4; /* 컬럼 개수 */
}
.container {
    width: calc(var(--item-width)*var(--column-count)); /* 전체 너비 자동 계산 */
    margin: 0 auto;
    column-count: var(--column-count);
    column-gap: 20px;
}

반응형 레이아웃을 만들려면 미디어쿼리로 "column-count" 변숫값을 조절해주면 됩니다.

웹 브라우저 너비가 1023px 이하이면 컬럼 개수를 3개로 줄이는 미디어 쿼리를 추가합니다.

@media screen and (max-width: 1023px){
    :root {
        --column-count: 3;
    }
}

웹 브라우저 너비 변화에 따라 가변으로 레이아웃 너비가 웹 브라우저 너비보다 작아지도록 하려면 다음과 같이 "container" 클래스의 너비 값을 "max-width"로 변경합니다.

.container {
    max-width: calc(var(--item-width)*var(--column-count));
}

아이템 안의 이미지들을 지우고, 아이템 높이를 다양하게 설정해서 확인하면 다음처럼 6번째 아이템이 중간에 잘려서 컬럼을 넘어가는 것을 확인할 수 있습니다.

메이슨리 이미지 목록을 만들 때는 이미지가 잘 릴 일이 없겠지만, 아이템 안에 텍스트 내용과 다양한 태그들을 함께 배치하면 아이템 중간이 잘려서 다음 컬럼으로 넘어가는 현상이 발생합니다.

이런 현상을 막으려면 아이템이 중간에 잘리지 않도록 속성을 추가해서 막아야 합니다. 아이템 클래스(item)에 "break-inside: avoid;" 속성을 추가합니다.

.item {
    break-inside: avoid; /* 아이템이 컬럼 사이에서 잘리지 않도록 방지 */
    margin: 0 0 20px 0;
    line-height: 0;
    width: 100%;
    background-color: #ccc;
    border-radius: 20px;
    overflow: hidden;
    box-shadow: 0 8px 20px -15px #000;
}