1. 소개
이 섹션은 규범적이지 않습니다.
그리드 레이아웃은 CSS에서 박스와 그 내용의 크기 및 위치 지정을 강력하게 제어할 수 있는 레이아웃 모델입니다. 그리드 레이아웃은 2차원 레이아웃에 최적화되어 있습니다: 콘텐츠의 정렬이 두 축 모두에서 필요한 경우에 적합합니다.

많은 레이아웃을 일반 그리드 레이아웃으로 표현할 수 있지만, 아이템을 두 축 모두에서 그리드로 제한하면 웹에서 흔히 볼 수 있는 몇 가지 레이아웃을 표현할 수 없게 됩니다.
이 모듈은 그 제한을 제거한 레이아웃 시스템을 정의하여, 아이템을 한 축에서만 그리드처럼 트랙에 배치하고, 다른 축에서는 순차적으로 쌓을 수 있습니다. 아이템은 지금까지 배치된 아이템들의 레이아웃 크기를 기준으로 가장 남은 공간이 많은 열(또는 행)에 배치됩니다. 이 모듈은 CSS Grid에 새로운 그리드 아이템 배치 전략을 확장하고, CSS Box Alignment에 새로운 정렬 기능을 추가합니다.
1.1. 배경 및 동기
1.1.1. 자동 배치 아이템의 워터폴 레이아웃
메이슨리 레이아웃은 때때로 “워터폴 레이아웃”이라고도 불리며, 여러 개의 아이템(주로 이미지 또는 짧은 기사 요약)이 마치 돌을 쌓는 것처럼 열에 하나씩 배치되는 일반적인 웹 디자인 패턴입니다. 멀티컬럼 레이아웃과 달리, 콘텐츠가 첫 번째 열에 수직으로 배치되다가 두 번째 열로 넘어가는 방식이 아닌, 메이슨리 레이아웃은 각 새 아이템이 일반적으로 레이아웃의 상단에 더 가까운 열을 선택하여 배치합니다.

여기서 각 아이템은 높이가 다릅니다 (콘텐츠 및 열의 너비에 따라 다름), DOM을 확인해 보면 (시각적 콘텐츠 자체로는 순서를 알 수 없지만) 각 아이템이 지금까지 가장 높이가 낮은 열에 배치된 것을 알 수 있습니다.
이 레이아웃은 겉보기에는 멀티컬럼 레이아웃과 비슷하지만, 아래로 스크롤하면 자연스럽게 레이아웃상 “나중”에 배치된 아이템(즉, 검색 결과에서 덜 관련된 아이템)으로 이어집니다.
이 레이아웃은 이전 CSS 레이아웃 모델만으로는 구현할 수 없습니다. 각 아이템의 높이를 미리 알거나, 자바스크립트로 콘텐츠 측정 또는 배치를 해야만 합니다.
메이슨리 컨테이너와 auto 배치 아이템을 함께 사용하면 이런 유형의 메이슨리 레이아웃을 만들 수 있습니다.
1.1.2. 1차원 그리드 레이아웃
그리드 레이아웃은 두 축 모두에서 강력한 트랙 크기 지정 및 명시적 배치를 제공하지만, 때로는 아이템의 한 방향 정렬만 필요한 경우가 있습니다.
메이슨리 컨테이너와 명시적으로 배치된 아이템을 함께 사용하면 이런 1차원 그리드 레이아웃을 만들 수 있습니다.

1.2. 값 정의
이 명세는 CSS 속성 정의 규칙을 [CSS2]에서 따르며, 값 정의 문법을 [CSS-VALUES-3]에서 따릅니다. 이 명세에서 정의하지 않은 값 타입은 CSS Values & Units [CSS-VALUES-3]에서 정의됩니다. 다른 CSS 모듈과 결합하여 이러한 값 타입의 정의가 확장될 수 있습니다.
각 속성 정의에 나열된 속성별 값 외에도, 이 명세에서 정의된 모든 속성은 CSS-wide 키워드도 속성 값으로 허용합니다. 가독성을 위해 명시적으로 반복하지 않았습니다.
2. 메이슨리 레이아웃 모델
메이슨리 레이아웃은 아이템을 미리 정의된 트랙에 배치하는데, 이는 그리드 레이아웃과 유사하지만 한 축(이를 그리드 축이라 함)에서만 적용됩니다. 다른 축(이를 스태킹 축이라 함)에서는 플렉스 레이아웃처럼 자유롭게 흐릅니다. 그리드 레이아웃과 유사하지만 플렉스 레이아웃과 다르게, 메이슨리 레이아웃의 자동 배치는 트랙 전체의 길이를 최대한 비슷하게 유지하도록 아이템을 분산시킵니다.
그리드 아이템은 일반 blockify 및 그리드 컨테이너와 동일하게 생성/처리됩니다.
(명확성을 위해, 그리드 아이템 및 그리드 트랙을 메이슨리 컨테이너에서는 메이슨리 아이템 및 메이슨리 트랙이라 지칭할 수 있습니다.)
별도 명시가 없는 한, 모든 CSS 속성은 일반 그리드 컨테이너에서와 동일하게 동작합니다. 예를 들어, order 속성을 사용해 아이템의 레이아웃 순서를 다르게 지정할 수 있습니다.
참고: 서브그리드 아이템도 지원되지만, 서브그리딩은 그리드 축에서만 발생합니다; 자세한 내용은 § 3.2 서브그리드 참고.
메이슨리 컨테이너는 그 내용이 메이슨리 레이아웃에 참여하는 박스입니다. 메이슨리 컨테이너는 컬럼 메이슨리 컨테이너 (스태킹 축이 블록 축일 때) 또는 행 메이슨리 컨테이너 (스태킹 축이 인라인 축일 때)로 분류됩니다.
컬럼 메이슨리 |
grid-template-columns: 1fr 2fr 3fr; | ![]() |
---|---|---|
행 메이슨리 |
grid-template-rows: 1fr 2fr 3fr; | ![]() |
2.1. 순서 변경 및 접근성
메이슨리 레이아웃은 일반적으로 앞쪽(현재 아이템 아래 또는 끝 방향)에 다음 아이템을 배치하여 자연스러운 "읽기 순서"를 따르지만, 두 방향을 임의로 전환할 수 있습니다. 간단한 경우에는 item-tolerance 속성을 사용해 블록 축의 작은 크기 차이로 인한 역방향 배치 느낌을 줄일 수 있습니다. 그러나 자동 배치와 명시적 배치 또는 확장 아이템이 혼합되면, 일부 역방향 배치가 발생할 수 있습니다.
< section class = masonry > < div class = item > 1</ div > < div class = item > 2</ div > < div class = "item tall" > 3</ div > < div class = "item wide" > 4</ div > < div class = item > 5</ div > < div class = item > 6</ div > < div class = item > 7</ div > </ section > < style > . masonry { //FIXMEdisplay : something ; grid-template-columns : repeat ( 5 , auto ); } . item { height : 50 px ; } . item . wide { grid-column : span 3 ; } . item . tall { height : 90 px ; } </ style >

작성자는 이러한 가능성을 인지하고, 역방향 배치가 최소화되어 포커스 및 읽기 순서가 더 쉽게 따라갈 수 있도록 레이아웃을 설계해야 합니다. 반대로, 아이템에 고유한 순서가 없다면 reading-flow 속성을 사용해 UA가 읽기 및 순차 탐색을 위해 아이템을 재배치하도록 할 수 있습니다.
여기서 자동 배치 아이템의 기본 동작이 순서 변경이어야 할까요?
-
item-tolerance에 적절한 값을 사용 (즉, 크기가 비슷한 트랙을 불필요하게 구분하지 않을 정도로 충분히 크지만, 의미 있는 차이를 무시하지 않을 정도로만 크게 설정)
-
명시적 배치를 사용해 관련 아이템을 함께 그룹화하도록 하되, 아이템의 자연스러운 순서를 방해하지 않도록 배치
-
그리드 축에서 혼합 스팬 크기와 스태킹 축에서 다양한 아이템 크기를 함께 사용하면 아이템이 순서에서 벗어날 수 있으니(위 예시 참고) 피하기
그리드 레이아웃 및 플렉스 레이아웃과 마찬가지로 작성자는 order 속성을 사용해 아이템의 순서를 변경할 수 있습니다; 동일한 주의사항이 적용됩니다. CSS Grid Layout 2 § 4 순서 변경 및 접근성 및 CSS Flexbox 1 § 5.4.1 순서 변경 및 접근성 참고.
2.2. 메이슨리 레이아웃 활성화
- something
- 이 값은 해당 요소가 메이슨리 컨테이너 박스를 생성하도록 합니다.
메이슨리 컨테이너가 그리드 축에 서브그리드되지 않은 경우, 그 컨텐츠에 대해 독립적인 포맷팅 컨텍스트를 설정합니다.
3. 메이슨리 트랙 명세
그리드 축에서는 그리드 레이아웃의 모든 트랙 명세 기능을 사용할 수 있습니다:
하지만, 자동 배치 아이템은 최종적으로 배치된 트랙뿐만 아니라 모든 트랙에 크기를 기여합니다; § 3.4 그리드 축 트랙 크기 지정 참고.
참고: 자동 배치 아이템은 배치 과정에서 레이아웃되어야 하므로, 각 트랙이 얼마나 "가득 찼는지"를 알아야 하며 (따라서 다음 자동 배치 아이템을 어떤 트랙에 둘지 결정할 수 있음), 그래서 트랙 자체가 이미 명확한 크기를 갖고 있어야 아이템이 레이아웃 중 사용 가능한 공간을 알 수 있습니다.
3.1. 메이슨리 트랙 템플릿 선언: grid-template-* 속성
grid-template-* 및 grid-auto-rows/grid-auto-columns 속성 (및 그 축약형들)은 그리드 축의 메이슨리 컨테이너에서 적용되어 일반 그리드 컨테이너와 동일하게 트랙을 생성합니다. (이 속성들은 스태킹 축에서는 무시됩니다.)
3.1.1. 내재 트랙 및 repeat()
자동 반복되는 콘텐츠 기반 트랙을 허용해야 할까요? 이에 대한 합리적 정의가 될까요? 그리드 레이아웃에서도 동작해야 할까요? [Issue #10915]
그리드 레이아웃에서는 모든 그리드 아이템이 그리드 트랙 크기가 지정되기 전에 그리드에 배치됩니다. 즉, auto-fill/auto-fit 반복은 auto와 같은 내재 크기 트랙을 포함할 수 없습니다 (repeat() 함수 내 또는 고정 부분의 트랙 목록에 함께 사용). 그 이유는 레이아웃 알고리즘이 해당 트랙에 어떤 아이템이 들어갈지 미리 알아야 하고, 트랙 크기를 알아야 하며, 사용 가능한 공간에 몇 번 반복되는지 결정해야 하기 때문입니다.
메이슨리 레이아웃에서는 메이슨리 아이템의 배치와 레이아웃이 서로 얽혀 있고 더 단순화되어 있으므로, 이 제한은 더 이상 엄격하게 필요하지 않습니다. 약간의 휴리스틱 크기 정의가 필요하지만, 자동 반복은 메이슨리 컨테이너에서 내재 크기 트랙을 포함할 수 있습니다.
-
명시적 아이템 배치는 무시합니다. (즉, 모든 아이템이 자동 위치라고 가정)
-
트랙을 축소하지 않습니다.
-
메이슨리 아이템이 스팬이 1보다 크면, 각 내재 크기 기여값에서 먼저 해당 스팬에 해당하는 갭 크기를 빼고, 스팬으로 나눕니다. 그런 다음, 스팬 1인 아이템이며 수정된 내재 크기 기여값을 갖는 것으로 처리합니다.
모든 트랙은 이 단순화된 레이아웃으로 계산된 크기를 갖는 것으로 처리합니다 (repeat() 인자 내의 트랙 포함, 해당 반복에서 가져옴) 이 크기를 바탕으로 repeat() 함수가 해석될 반복 횟수를 결정합니다.
동기
이 단순화된 레이아웃 휴리스틱은 "충분히 괜찮은" 결과를 내면서 빠르고 일관되도록 정의되었습니다.
배치를 무시하는 것은 개념을 일관되게 만들기 위해 필요합니다; 얼마나 반복해야 할지 알기 전에, 명확한 위치를 가진 아이템이 어느 트랙에 들어갈지 알 수 없습니다.
스팬 아이템을 스팬 1 아이템으로 쪼개면, repeat()을 여러 번 확장해야 하는 상황을 피할 수 있고, 각 반복에서 동일한 키워드가 서로 다른 크기를 갖는 불일치도 방지됩니다.
전체 레이아웃 비용도 크게 줄어듭니다. 고유 트랙 크기만 고려하면 되므로, repeat() 확장을 실제로 할 필요도 없습니다. 즉, auto repeat(auto-fill, min-content auto)에서는 두 auto 키워드는 이 휴리스틱 레이아웃에서 같은 크기로 해석됩니다; auto와 min-content 트랙 크기로 각각 결과를 내면 됩니다.
3.2. 서브그리드
서브그리드는 중첩된 메이슨리 컨테이너와 그리드 컨테이너가 트랙 크기를 공유할 수 있게 합니다. 부모의 해당 축이 그리드 축인 경우, 서브그리드된 축은 부모 컨테이너에서 그리드 컨테이너 규정대로 가져옵니다; 부모의 해당 축이 스태킹 축인 경우, 서브그리드된 축은 masonry처럼 동작합니다.
참고: 만약 두 축 모두 masonry가 되면, 이는 메이슨리 컨테이너의 양축 masonry 템플릿과 동일하게 처리됩니다. 즉, grid-template-columns: none; grid-template-rows: masonry과 같이 동작합니다.
메이슨리 레이아웃에서는 자동 배치 서브그리드는 부모 그리드의 라인 이름을 상속받지 않습니다. 그렇게 되면 아이템의 배치가 레이아웃 결과에 의존하게 되기 때문입니다; 하지만 서브그리드의 트랙은 부모의 트랙에 여전히 맞춰 정렬됩니다.
<style> .grid{ //FIXME: display: inline something; grid-template-rows : auto auto100 px ; align-content : center; height : 300 px ; border : 1 px solid; } .grid > *{ margin : 5 px ; background : silver; } .grid >:nth-child ( 2 n ) { background : pink; } .grid subgrid{ display : grid; grid : subgrid / subgrid; grid-row : 2 / span2 ; grid-gap : 30 px ; } .grid subgrid > *{ background : cyan; } </style>
< div class = "grid" > < item > 1</ item > < item > 2</ item > < item > 3</ item > < subgrid > < item style = "height:100px" > subgrid.1</ item > < item > sub.2</ item > < item > s.3</ item > </ subgrid > < item > 4</ item > < item > 5</ item > < item style = "width: 80px" > 6</ item > < item > 7</ item > </ div >

서브그리드의 첫 번째 아이템("subgrid.1")이 부모 그리드의 두 번째 행의 내재 크기에 기여하는 점을 확인하세요. 서브그리드가 명확한 위치를 지정했기 때문에 어떤 트랙을 차지하는지 알 수 있습니다. 부모의 스태킹 축을 서브그리드화하려 하면 서브그리드가 메이슨리 레이아웃을 인라인 축에서 갖게 됨을 주의하세요.
서브그리드 중 메이슨리 컨테이너는 서브메이슨리라 할 수 있습니다.
3.3. 트랙 반복: repeat() 표기법
이 명세는 repeat() 표기법에 대해 새로운 키워드와 메이슨리 전용 동작을 도입합니다.
3.3.1. repeat(auto-areas)
새로운 auto-areas 값은 repeat() 표기법에서, 전체 명시적 트랙 수가 해당 축에서 적용 중인 grid-template-areas 값과 일치하도록 반복 횟수를 나타냅니다. 여러 트랙이 반복에 나열된 경우, 마지막 반복은 필요한 만큼 잘려서 적절한 트랙 수가 만들어집니다.
참고: auto-fit과 달리—항상 최소 1회 반복되고 트랙 목록 전체를 반복함— auto-areas의 반복 횟수는 0이 될 수 있고 (이미 충분한 명시적 트랙이 있다면), 마지막 반복이 부분적일 수 있습니다.
grid-template-areas가 none이면, 이 값은 auto-fit처럼 동작합니다.
참고: 이 값은 일반 그리드 컨테이너와 메이슨리 컨테이너 모두에 적용됩니다.
실제로 이 값이 필요한지 불분명합니다. 명시적 그리드는 이미 grid-auto-columns/grid-auto-rows 값으로 템플릿 영역 수에 맞춰 값을 가져옵니다. [Issue #10854]
3.3.2. repeat(auto-fit)
메이슨리 컨테이너(일반 그리드 컨테이너와 동일하게)에서 auto-fit은 auto-fill과 같이 동작하지만, 비어 있는 트랙을 축소합니다. 그러나 배치가 트랙 크기 지정 이후에 발생하므로, 메이슨리 컨테이너는 해당 트랙이 점유될지 판단하기 위해 휴리스틱을 사용합니다:
-
명시적으로 배치된 아이템이 점유하는 모든 트랙은 점유된 것으로 간주합니다.
-
자동 배치 아이템의 스팬 합계가 N일 때, 점유되지 않은 트랙 중 N번째까지의 모든 트랙을 점유된 것으로 간주합니다.
auto-fit 반복으로 생성되고 이 휴리스틱에서 점유되지 않은 트랙은 "비어 있음"으로 간주되어 축소됩니다. 축소된 트랙에는 자동 배치 아이템을 배치할 수 없습니다.
참고: auto-fill을 사용할 때 자동 배치 아이템이 트랙에 배치될 수 있지만, auto-fit을 사용할 경우 스팬이 1보다 큰 자동 배치 아이템이 명시적으로 배치된 아이템과 섞여 있어, 자동 배치 아이템이 들어갈 수 없을 만큼 작은 갭이 남는 경우 해당 트랙이 축소될 수 있습니다.
3.4. 그리드 축 트랙 크기 지정
트랙 크기 지정은 CSS Grid와 동일하게 동작하지만, 내재 크기에 기여하는 아이템을 고려할 때 아래와 같이 다릅니다:
-
해당 트랙에 명시적으로 배치된 모든 아이템이 기여하며,
-
자동 그리드 위치를 갖는 모든 아이템이 기여합니다 (최종적으로 해당 트랙에 배치되는지와 상관없이).
-
A, B, C 아이템은 명시적 위치가 없습니다.
-
D 아이템은 첫 번째 열에 명시적으로 배치됩니다.
이 경우, A, B, C, D 모두가 첫 번째 열의 크기 지정에 기여하며, 두 번째 열에는 D를 제외한 A, B, C만 기여합니다.
자동 그리드 위치를 지닌 아이템이 여러 트랙을 span하는 경우, 모든 가능한 시작 위치에 배치된 것으로 가정하여 해당 트랙에 기여합니다.
-
그리드 라인 1에서는, 첫 두 트랙 각각에 110px 기여.
-
그리드 라인 2에서는, 두 번째 트랙에 120px 기여.
-
그리드 라인 3에서는, 네 번째 트랙에 120px 기여.
-
그리드 라인 4에서는, 네 번째와 다섯 번째 트랙 각각에 110px 기여.
참고: 이 알고리즘은 각 트랙이 최종적으로 배치될 모든 아이템을 수용할 수 있을 만큼 충분히 크게 보장하며, 배치와 트랙 크기 지정 사이에 의존성 사이클을 만들지 않습니다. 하지만 크기 변동에 따라 트랙이 필요 이상으로 커질 수 있습니다: 모든 아이템이 그리드 축에 명시적으로 배치되거나, 모든 아이템 크기가 같을 때(또는 span하는 아이템의 경우 그 크기의 배수일 때)만 정확한 맞춤이 보장됩니다.
3.4.1. 서브그리드 아이템 기여
일반 그리드 컨테이너나 메이슨리 컨테이너의 트랙 크기 지정 시, 서브메이슨리는 자동 그리드 위치를 갖는 아이템을 특별하게 처리합니다:
-
이런 아이템은 서브메이슨리가 span할 수 있는 모든 그리드 트랙에 배치된 것으로 간주합니다. (서브메이슨리가 명확한 그리드 위치를 갖는 경우, 해당 트랙만; 자동 그리드 위치인 경우, 부모 그리드의 모든 트랙.)
-
이런 아이템은 배치될 수 있는 각 엣지마다 가장 큰 margin/border/padding 기여값을 갖습니다. 아이템이 서브그리드 전체를 span하면 양쪽 엣지 모두 적용됩니다. (CSS Grid Layout §9 참고)
3.4.2. 최적화된 트랙 크기 지정
트랙 크기 지정은 동일한 span 크기와 배치를 가진 아이템을 하나의 가상 아이템으로 집계하여 다음과 같이 최적화할 수 있습니다:
-
아래 속성에 따라 모든 메이슨리 아이템을 아이템 그룹으로 나눕니다:
-
아이템의 span값
-
아이템의 배치(어떤 트랙에 배치될 수 있는지)
참고: 예를 들어, span 2인 아이템이 두 번째 트랙에 배치된 경우, span 2이지만 자동 그리드 위치를 갖는 아이템과는 다른 그룹이 됩니다.
-
-
각 아이템 그룹에 대해, 해당 그룹 내 아이템 중 내재
크기 기여값이 가장 큰 값으로 가상
메이슨리 아이템을 합성합니다.
아이템이 baseline 정렬을 적용한다면, 가상 메이슨리 아이템의 baseline은 모든 아이템을 하나의 가상 그리드 트랙에 배치하여 공유 baseline 및 shim을 찾습니다. 이에 따라 그룹의 내재 크기 기여값을 증가시킵니다.
- 각 가상 메이슨리 아이템을 그리드 축 트랙의 가능한 모든 위치에 가상으로 복사해 배치하고, 트랙 크기 지정 알고리즘을 실행합니다. 결과 트랙 크기가 메이슨리 컨테이너의 트랙 크기가 됩니다.
참고: 이 최적화는 위 트랙 크기 지정 설명과 동일한 결과를 내야 합니다; 만약 다르다면 오류이므로 CSSWG에 보고해주세요.
4. 메이슨리 배치
그리드 축에서는 아이템을 명시적으로 배치하여 트랙에 span시킬 수 있으며, 친숙한 grid-placement 속성 문법을 사용합니다. 자동 배치는 § 4.4 메이슨리 레이아웃 및 배치 알고리즘을 사용하며, 자동 그리드 위치를 갖는 각 아이템을 가능한 가장 "짧은" 메이슨리 트랙에 배치합니다.
4.1. 메이슨리 아이템 배치 지정: grid-column-* 및 grid-row-* 속성
grid-column-* 및 grid-row-* 속성(및 그 축약형)은 아이템의 그리드 축에 적용되어 일반 그리드 레이아웃과 동일하게 배치를 지정합니다.
4.2. 배치 정밀도: item-tolerance 속성
이름: | item-tolerance |
---|---|
값: | normal | <length-percentage> | infinite |
초기값: | normal |
적용 대상: | 메이슨리 컨테이너 |
상속됨: | 아니오 |
백분율: | 그리드 축 content box 크기에 상대적 메이슨리 컨테이너 |
계산된 값: | 계산된 <length-percentage> 값 |
정규 순서: | 문법 기준 |
애니메이션 타입: | 길이로써 |
메이슨리 컨테이너는 각 메이슨리 아이템을 현재 가장 덜 채워진 메이슨리 트랙에 배치하여 채웁니다. 여러 트랙이 동일하게 덜 채워진 경우, 순서대로 배치하면 보기 좋습니다. 하지만 트랙 높이가 매우 약간만 다를 경우, 순서대로 채워지지 않으면 이상하게 보일 수 있습니다. 높이 차이가 의미있게 다르게 인식되지 않기 때문입니다.
item-tolerance 속성은 트랙을 "동일 높이"로 간주하는 임계값을 지정하여, 트랙이 순서대로 채워지도록 만듭니다.
- <length-percentage>
-
tie threshold를 메이슨리 컨테이너에 지정합니다. 배치 위치가 최단 위치에서 지정된 거리 내에 있으면 동등하게 좋은(“tie”) 것으로 간주합니다.
참고: 초기값은 "작은" 거리(1em)로, "충분히 가까움"을 표현하기에 적절할 것입니다.
- normal
-
used value가 메이슨리 레이아웃에서 1em으로, 다른 레이아웃 모드에서는 used value 0으로 해석됩니다.
- infinite
-
무한대 tie threshold를 지정합니다. 이 값은 아이템을 완전히 순서대로 분배하게 하며, 트랙의 길이를 전혀 고려하지 않습니다.
참고: 이 값은 연속된 아이템이 스태킹 축에서 매우 다른 위치에 배치될 수 있어 독자에게 혼란을 줄 수 있습니다. 초기값(`1em`)이 너무 작다면, `infinite` 대신 더 큰 값(예: `10em` 또는 `50vh`)을 고려하세요.
CSSWG는 이 속성의 더 좋은 이름을 환영합니다. [Issue #10884]
참고: 향후 플렉스 레이아웃에도 이 속성을 적용할 예정이며, 관련 논의 참고.
4.3. 조밀한 배치: dense 키워드
그리드 레이아웃에서 grid-auto-flow: dense는 그리드 아이템 배치 알고리즘에서 역방향 배치를 허용합니다. dense 키워드도 메이슨리 배치 알고리즘에서 역방향 배치를 허용합니다. 하지만 메이슨리 배치와 크기 지정이 얽혀 있으므로, 아이템은 해당 슬롯의 트랙 사용 크기 총합이 현재 일반 배치 트랙의 사용 크기와 일치할 때만 빈 슬롯으로 역방향 배치할 수 있습니다.
참고: 이 제한은 아이템을 여러 번 레이아웃하는 것을 방지합니다.
4.4. 메이슨리 레이아웃 및 배치 알고리즘
그리드 축의 각 트랙에, 0으로 초기화된 실시간 위치를 유지합니다. 자동 배치 커서도 유지하며, 처음에는 첫 번째 라인을 가리킵니다.
순서 수정된 문서 순서의 각 아이템에 대해:
-
아이템이 명확한 그리드 위치를 그리드 축에 갖는 경우,
해당 배치를 사용합니다.
그렇지 않으면, 아래 하위 단계를 통해 그리드 축 배치를 해석합니다:
- 그리드 축의 첫 번째 라인부터 시작하여, 해당 라인에 아이템을 배치했을 때 span하는 트랙 중 가장 큰 실시간 위치를 찾고, 이를 max_pos라 합니다.
- 이전 단계를 아이템이 그리드에 더 이상 들어갈 수 없을 때까지 각 라인 번호에 대해 반복합니다.
- possible lines를 max_pos가 가장 작은 라인 및, tie threshold 내에 있는 모든 라인으로 합니다.
- 자동 배치 커서 이상인 possible lines의 첫 번째 라인을 아이템의 그리드 축 위치로 선택합니다; 없다면 첫 번째를 선택합니다.
- 자동 배치 커서를 아이템의 마지막 라인으로 업데이트합니다.
- 아이템을 해당 그리드 축 트랙에 배치합니다. span하는 트랙 중 실시간 위치가 가장 큰 위치에 배치합니다.
- 아이템의 포함 블록 크기를 계산한 후 레이아웃합니다.
span된 그리드 축 트랙의 실시간 위치를
max_pos + outer size + grid-gap
로 설정합니다. -
메이슨리 컨테이너가 dense 패킹을 사용할 때,
레이아웃에(예: span 아이템 때문에) 건너뛴 빈 공간이 있고,
현재 크기로 그 공간에 더 일찍 배치될 수 있으며,
span된 트랙의 사용 크기 총합이 현재 배치된 트랙과 같다면,
가장 높은 그런 공간에 배치합니다.
tie
threshold 내에 여러 공간이 있다면,
start에 가장 가까운 곳에 배치합니다.
자동 배치 커서와
실시간 위치를 해당 아이템 배치 전
값으로 되돌립니다.
참고: 조밀한 패킹은 역방향 채우기시 자동 배치 커서를 무시하고, 배치 후 커서를 업데이트하지 않습니다. 적절한 역방향 배치 공간이 없으면, dense가 지정되지 않은 경우와 동일하게 배치합니다.
참고: 이 알고리즘은 아이템이 가능한 가장 높은 위치에 배치되도록 트랙을 선택합니다. 동점이 있으면, 가능하면 가장 최근 배치된 아이템 이후의 가장 이른 트랙을 선택하여 항상 "앞으로" 이동하도록 합니다.
4.4.1. 포함 블록
포함 블록은 그리드 아이템이 메이슨리 레이아웃에 참여할 때, 그리드 영역의 그리드 축과 그리드 컨테이너의 content box의 스태킹 축으로 형성됩니다.
4.4.2. 배치 및 작성 모드
참고: 그리드 레이아웃과 마찬가지로, 메이슨리 레이아웃 및 배치는 작성 모드에 민감합니다. 예를 들어 direction: rtl의 경우, 인라인 축이 그리드 축이든 스태킹 축이든, 아이템은 좌→우가 아니라 우→좌로 배치됩니다.
<style> .grid{ //FIXME display: inline something; direction : rtl; grid-template-columns : repeat ( 4 , 2 ch ); border : 1 px solid; } item{ background : silver} item:nth-child ( 2 n +1 ) { background : pink; height : 4 em ; } </style>
< div class = "grid" > < item > 1</ item > < item style = "grid-column:span 2" > 2</ item > < item > 3</ item > < item > 4</ item > </ div >

<style> .grid{ //FIXME display: inline something; direction : rtl; width : 10 ch ; column-gap : 1 ch ; grid-template-rows : repeat ( 4 , 2 em ); border : 1 px solid; } item{ background : silver} item:nth-child ( 2 n +1 ) { background : pink; width : 4 ch ; } </style>
< div class = "grid" > < item > 1</ item > < item style = "grid-row:span 2" > 2</ item > < item > 3</ item > < item > 4</ item > </ div >

5. 그리드 컨테이너 크기 지정
그리드 컨테이너 크기 지정은 일반 그리드 컨테이너와 동일하게 동작하지만 스태킹 축에서는 다음과 같은 부가사항이 있습니다: 그리드 컨테이너의 스태킹 축에서의 max-content 크기(min-content 크기)는 해당 축에서 masonry box가 max-content constraint(min-content constraint) 아래에서 크기가 지정된 값입니다.
<style> .grid{ //FIXME display: inline something; grid-template-columns : 50 px 100 px auto; grid-gap : 10 px ; border : 1 px solid; } item{ background : silver; margin : 5 px ; } </style>
< div class = "grid" > < item style = "border:10px solid" > 1</ item > < item > 2</ item > < item > 3</ item > < item style = "height:50px" > 4</ item > < item > 5</ item > < item > 6</ item > </ div >

6. 정렬 및 간격
거터는 두 축 모두에서 지원됩니다. 스태킹 축에서는 gap이 각 인접 아이템 쌍의 margin box 사이에 적용됩니다. 마진은 어느 축에서도 병합되지 않습니다.
그리드 축에서는 정렬이 일반 그리드 컨테이너와 동일하게 동작합니다.
스태킹 축에서는 전체 콘텐츠 분배가 블록 컨테이너에서와 유사하게 적용됩니다. 더 구체적으로, 정렬 대상은 masonry box이며, 이는 모든 margin box를 감싸는 최소 사각형입니다.

참고: 정렬 대상은 스태킹 축에서 항상 하나만 존재하며, align-content / justify-content 값은 start, center, end, 그리고 baseline 정렬로 단순화됩니다. (normal 및 stretch의 동작은 start와 동일하며, 분산 정렬 값은 fallback 정렬에 따라 동작합니다.) 그리드 아이템이 그리드 컨테이너의 content box를 스태킹 축에서 넘치면, masonry box가 그리드 컨테이너의 content box보다 커집니다.
스태킹 축에서 정렬이 더 정교하게 동작해야 할까요? 어떻게 해야 할까요?
6.1. 기준선 정렬
기준선 정렬은 그리드 축 트랙 내에서 일반 그리드 컨테이너와 동일하게 동작하며, 그리드 컨테이너의 기준선은 해당 축에서 일반 그리드 컨테이너와 동일하게 결정됩니다.
기준선 정렬은 스태킹 축에서는 지원되지 않습니다. 이 축에서 그리드 컨테이너의 첫 번째 기준선 집합은 각 트랙의 첫 번째로 배치된 정렬 기준선 중 가장 높은 값에서 생성되며, 마지막 기준선 집합은 각 트랙의 마지막으로 배치된 정렬 기준선 중 가장 낮은 값에서 생성됩니다.
첫 번째 행에서 기준선 정렬을 지원할 수 있습니다. 원하시나요?
마지막 기준선이 마지막으로 가장 낮은 아이템에서 오도록 해야 할까요?
7. 단편화
7.1. 스태킹 축의 단편화
그리드 축의 각 트랙은 스태킹 축에서 독립적으로 단편화됩니다. 그리드 아이템이 단편화되거나, 강제 분할이 아이템 앞/뒤에 있으면, 해당 아이템이 span하는 그리드 축 트랙의 실시간 위치는 fragmentainer의 크기로 설정되어 해당 트랙에 더 이상 아이템이 배치되지 않습니다. 여러 조각으로 분할된 아이템은 모든 조각에서 그리드 축의 배치를 유지합니다. 밀려난 그리드 아이템은 다음 그리드 컨테이너 fragment에서 다시 배치됩니다. 모든 아이템이 배치되거나 새 fragment로 밀려날 때까지 배치가 계속됩니다.
7.2. 그리드 축의 단편화
그리드 축에서 메이슨리 레이아웃이 다른 축에서 사용되는 경우에도 단편화가 지원됩니다. 이 경우 단편화는 일반 그리드 컨테이너와 유사하게 동작하지만, 단편화 전 각 아이템이 배치될 그리드 축 트랙을 결정하는 별도 단계가 있습니다.
8. 절대 위치 지정
그리드 정렬 절대 위치 자손은 메이슨리 컨테이너에서 일반 그리드 컨테이너와 동일하게 지원됩니다; 하지만 스태킹 축에서는 배치 가능한 라인이 두 개(추가로 auto 라인 포함)만 존재합니다:
-
line 1 (line -2)은 masonry box의 시작 엣지에 대응합니다
-
line 2 (line -1)은 masonry box의 끝 엣지에 대응합니다
스태킹 축에서 static 위치를 정의하는 것이 유용할 수 있습니다. 현재 그리드 축 트랙의 실시간 위치의 최대값(또는 최소값?)이나 그 앞의 아이템 끝으로 정의할 수 있지 않을까요?
9. 점진적 저하
대개, 메이슨리 디자인은 그리드 레이아웃은 지원하지만 메이슨리 레이아웃을 지원하지 않는 UA에서도 비교적 잘 저하됩니다.
예시가 이를 설명합니다.
display : grid; display : something; /* 메이슨리 레이아웃을 지원하지 않는 UA에서 무시됨 */ grid-template-columns:150 px 100 px 50 px ;
이 코드는 3열 레이아웃을 만듭니다. 하지만 UA가 메이슨리 레이아웃을 지원하지 않으면 block 축에 "더 많은 갭"이 생깁니다. 메이슨리 지원이 있을 때의 비교 렌더링은 다음과 같습니다:
부록 A: 일반 레이아웃 아이템 흐름 제어: item-* 속성
이 섹션은 [css-display-4] 등 다른 명세로 이동될 가능성이 높습니다. 여러 display 타입에 영향을 주기 때문입니다.
CSS의 여러 레이아웃 모드는 자식들을 행/열로 구성된 원자적 "아이템"으로 배치하며, 작성자가 그 순서와 배치를 구성할 수 있도록 합니다. item-* 속성은 이러한 순서 및 배치 옵션을 위한 일반 제어를 제공하며, 레이아웃별 flex-flow 및 grid-auto-flow 속성을 캡슐화합니다.
흐름 중심 제안 | 트랙 중심 제안 | 값 공간 | 설명 | 기존 flex 속성 | 기존 grid 속성 |
---|---|---|---|---|---|
item-direction | item-track | auto | row | column | row-reverse | column-reverse | 아이템이 행 또는 열에 배치될지, 그리고 해당 트랙 내에서 시작→끝 또는 끝→시작 순서로 배치될지 제어합니다. | flex-direction | grid-auto-flow |
item-wrap | item-cross | [ auto | nowrap | wrap ] || [ normal | reverse ] | wrap-reverse | 아이템이 행/열 반대 축에서 wrap될지 여부, 그리고 wrap될 경우 시작→끝 또는 끝→시작 순서로 배치될지 제어합니다. | flex-wrap | 이 레벨에서 grid-auto-flow에 도입됨 |
item-pack | item-pack | normal | dense || balance | 아이템이 트랙에 어떻게 채워질지 구성합니다. | grid-auto-flow | |
item-tolerance | item-tolerance | normal | <length-percentage> | infinite | 배치 결정에 레이아웃별 "여유" 양을 정의합니다. |
CSSWG는 이러한 속성의 이름과 구조를 아직 조정 중입니다. [Issue #11480]
아이템 흐름 축: item-track/item-direction
이름: | item-direction, item-track |
---|---|
값: | auto | row | column | row-reverse | column-reverse |
초기값: | auto |
적용 대상: | flex 컨테이너, 그리드 컨테이너, 메이슨리 컨테이너 |
상속됨: | 아니오 |
백분율: | N/A |
계산된 값: | 지정된 대로 |
정규 순서: | 문법 기준 |
애니메이션 타입: | 불연속 |
이 속성은 아이템이 행 또는 열로 배치될지, 해당 트랙 내에서 시작→끝 또는 끝→시작 순서로 배치될지 제어합니다.
이 속성에 대해 두 가지 논쟁이 남아 있습니다: a) 이름을 어떻게 할지 b) 배치의 주 방향을 정의하는지, 아니면 아이템이 배치될 트랙의 방향을 정의하는지; 즉, 이 속성으로 정의되는 주 축이 주 배치 축인지 주 트랙 축인지. 이는 플렉스 레이아웃과 그리드 레이아웃에서는 같지만, 메이슨리 레이아웃에서는 주 배치 방향이 트랙을 가로지릅니다. [Issue #11480]
- auto
-
레이아웃 모드에 따라 row 또는 column으로 계산됩니다:
-
메이슨리 컨테이너에서는, grid-template-rows가 none이 아니고 grid-template-columns가 none이면, 행 트랙을 나타내는 값으로 계산됩니다; 그렇지 않으면 열 트랙을 나타내는 값으로 계산됩니다.
- row
-
트랙 중심 옵션 행에 배치함을 나타냅니다. 즉, 인라인 축에 평행한 트랙/라인. 아이템은 해당 행을 시작→끝 순서로 채웁니다.
흐름 중심 옵션 행 우선 배치, 즉 인라인 축에서 아이템을 시작→끝으로 배치, 플렉스 레이아웃에서는 flex row line을, 메이슨리 레이아웃에서는 그리드 column 트랙을 생성함.
- column
-
트랙 중심 옵션 열에 배치함을 나타냅니다. 즉, 블록 축에 평행한 트랙/라인. 아이템은 해당 열을 시작→끝 순서로 채웁니다.
흐름 중심 옵션 열 우선 배치, 즉 블록 축에서 시작→끝으로 배치, 플렉스 레이아웃에서는 flex column line을, 메이슨리 레이아웃에서는 그리드 row 트랙을 생성함.
- row-reverse
-
row와 동일하나 끝→시작 순서로 배치합니다.
- column-reverse
-
column과 동일하나 끝→시작 순서로 배치합니다.
아이템 교차 축 배치 모드: item-cross/item-wrap
이름: | item-wrap, item-cross |
---|---|
값: | [ auto | nowrap | wrap ] || [ normal | reverse ] | wrap-reverse |
초기값: | auto |
적용 대상: | flex 컨테이너, 그리드 컨테이너, 메이슨리 컨테이너 |
상속됨: | 아니오 |
백분율: | N/A |
계산된 값: | 지정된 대로 |
정규 순서: | 문법 기준 |
애니메이션 타입: | 불연속 |
주 축과 반대 축에서의 배치를 제어합니다.
- auto
- nowrap
-
아이템은 주 배치 축에 공간이 부족해도 계속 배치됩니다. 플렉스 레이아웃에서는 단일 라인 flex 컨테이너가 되고, 그리드 레이아웃에서는 암시적 트랙이 주 배치 축에 필요에 따라 생성됩니다.
- wrap
-
주 배치 축의 공간이 부족하면 아이템이 wrap됩니다. 플렉스 레이아웃에서는 다중 라인 flex 컨테이너가 되고, 그리드 레이아웃에서는 자동 배치 알고리즘이 주 배치 축에서 명시적 트랙이 다 소진되면 다음 행/열로 이동합니다.
- normal
-
아이템은 주 트랙 축과 반대 축에서 시작→끝 순서로 배치됩니다.
플렉스 레이아웃 및 그리드 레이아웃에서는 새 트랙(플렉스 라인 또는 그리드 트랙)이 배치되는 방향을 제어합니다.
메이슨리 레이아웃에서, 트랙 중심 문법에서는 여러 트랙이 높이가 같을 때 어떤 트랙을 선택할지 제어, 흐름 중심 문법에서는 트랙 내 아이템이 어떤 방향으로 채워질지 제어
- reverse
-
아이템은 주 트랙 축과 반대 축에서 끝→시작 순서로 배치됩니다.
- wrap-reverse
-
wrap reverse로 계산됩니다.
참고: 이 값은 기존 flex-wrap 값과의 일관성을 위해 존재합니다.
이 속성의 해석 및 명명은 item-direction/item-track의 축 해석에 따라 달라집니다. [Issue #11480]
아이템 배치 패킹 모드: item-pack 속성
이름: | item-pack |
---|---|
값: | normal | dense || balance |
초기값: | normal |
적용 대상: | flex 컨테이너, 그리드 컨테이너, 메이슨리 컨테이너 |
상속됨: | 아니오 |
백분율: | N/A |
계산된 값: | 지정된 대로 |
정규 순서: | 문법 기준 |
애니메이션 타입: | 불연속 |
이 속성은 아이템이 트랙에 어떻게 분배될지 레이아웃 특화 방식으로 제어합니다.
- normal
-
레이아웃 모드의 기본 패킹 전략을 사용합니다.
- dense
-
이전 공간(건너뛴 공간)에 아이템을 역방향 배치(backtracking)할 수 있게 합니다. (이전 아이템이 해당 공간에 너무 커서 건너뛴 경우 이런 공간이 생길 수 있음)
예를 들어, 플렉스 레이아웃에서는 남은 빈 공간이 충분한 이전 라인에 아이템을 배치할 수 있게 합니다.
- balance
-
플렉스 레이아웃에서는 각 라인(마지막 라인 포함)의 콘텐츠 양을 균형 있게 배분합니다. (text-wrap-style: balance와 유사)
메이슨리 레이아웃 전환 제안 중 하나는 item-pack 속성에 collapse 값을 추가하는 것입니다. [Issue #11243]
dense 패킹이 메이슨리에 적용되어야 할까요? 메이슨리에서는 모든 빈 공간에 아이템을 레이아웃해봐야 하므로 비용이 훨씬 큽니다; 그리드는 단순히 정수만 조작하면 됩니다. [Issue #9326]
아이템 배치 축약형: item-flow 축약형
이름: | item-flow |
---|---|
값: | <'item-direction'> || <'item-wrap'> || <'item-pack'> || <'item-tolerance'> |
초기값: | 각 개별 속성 참고 |
적용 대상: | 각 개별 속성 참고 |
상속됨: | 각 개별 속성 참고 |
백분율: | 각 개별 속성 참고 |
계산된 값: | 각 개별 속성 참고 |
애니메이션 타입: | 각 개별 속성 참고 |
정규 순서: | 문법 기준 |
이 축약 속성은 모든 item-* 개별 속성을 한 번에 설정합니다.
10. 감사의 글
Cameron McCormack에게 감사드립니다. 그는 메이슨리 레이아웃 설명 문서를 작성하여 CSSWG에 발표했고, 그 문서에서 배경 챕터를 가져왔습니다. 그리고 Mats Palmgren에게도 감사드립니다. 그는 이 명세의 초기 버전을 개발했습니다. 또한 이 기능의 초기 제안에 피드백을 주신 모든 분들께도 감사드립니다.
11. 보안 고려사항
이 명세는 레이아웃 명세이므로, CSS 레이아웃이 일반적으로 노출하는 것 외에 새로운 보안 고려사항을 추가하지 않습니다.
12. 개인정보 보호 고려사항
이 명세는 레이아웃 명세이므로, CSS 레이아웃이 일반적으로 노출하는 것 외에 새로운 개인정보 보호 고려사항을 추가하지 않습니다.
변경 사항
레벨 2 이후의 추가 사항
다음 기능이 레벨 2 이후 추가되었습니다:
- 메이슨리 레이아웃이 추가됨.
- item-flow 속성과 그 개별 속성이 아이템 순서 및 배치에 대한 일반 제어로 추가됨. 부록 A: 일반 레이아웃 아이템 흐름 제어: item-* 속성 참고. (이슈 11480)
최근 변경 사항
다음 변경 사항이 2024년 10월 3일 워킹 드래프트 이후 적용되었습니다: