1. 소개
이 섹션은 규범적이지 않습니다.
그리드 레이아웃은 CSS에서 박스와 그 내용의 크기 및 위치 지정을 강력하게 제어할 수 있는 레이아웃 모델입니다. 그리드 레이아웃은 2차원 레이아웃에 최적화되어 있습니다: 콘텐츠의 정렬이 두 축 모두에서 필요한 경우에 적합합니다.
많은 레이아웃이 일반 그리드 레이아웃으로 표현될 수 있지만, 아이템을 양 축 모두 그리드에 제한하면 웹에서 흔히 사용되는 일부 레이아웃을 표현할 수 없게 됩니다.
이 모듈은 그리드 레이아웃의 변형을 정의하며, 해당 제한을 제거하여 아이템을 한 축에서는 그리드 트랙에 배치하면서, 다른 축에서는 순차적으로 쌓을 수 있도록 합니다. 특정 트랙에 명시적으로 배치되지 않은 아이템은 지금까지 배치된 아이템의 레이아웃 크기를 기준으로 가장 공간이 많이 남아있는 열(또는 행)에 배치됩니다.
1.1. 배경 및 동기
1.1.1. 자동 배치 아이템을 사용한 워터폴 레이아웃
그리드 레인 레이아웃은 때로 “매니(머슨리) 레이아웃” 또는 “워터폴 레이아웃”이라 불리며, 여러 개의 아이템(주로 이미지나 짧은 기사 요약 등)이 하나씩 열에 배치되는, 벽돌쌓기와 유사한 웹 디자인 패턴입니다. 멀티 컬럼 레이아웃 및 멀티라인 컬럼 플렉스 레이아웃과 달리, 내용이 첫 번째 열에 세로로 채워지다가 두 번째 열로 넘어가는 것이 아니라, 자동 배치를 사용하는 그리드 레인 레이아웃에서는 새 아이템이 레이아웃 상단에 더 가깝도록 각 아이템의 열을 선택합니다.
여기서는 각 아이템이 다른 높이를 가지고 (내용 및 열의 너비에 따라 다름), DOM을 검사해 보면 (시각적인 내용만으로는 순서를 알 수 없음) 각 아이템이 그 시점에서 가장 낮은 열에 배치되어 있는 것을 확인할 수 있습니다.
이 레이아웃은 겉보기에 멀티 컬럼 레이아웃과 비슷하게 보이지만, 아래로 스크롤할수록 자연스럽게 레이아웃의 “뒷쪽” 아이템들 (예: 검색 결과에서 덜 관련된 항목)에 접근하게 된다는 장점이 있습니다.
이전 CSS 레이아웃 모델로는, 모든 아이템의 높이를 미리 알거나 자바스크립트로 콘텐츠를 측정하거나 배치하지 않는 한, 이 레이아웃을 구현할 수 없습니다.
display: grid-lanes와 grid-template-columns 를 함께 사용하면 이러한 그리드 레인 레이아웃이 구현됩니다.
1.1.2. 1차원 그리드 레이아웃
그리드 레이아웃은 강력한 트랙 크기 조정과 두 축에 대한 명시적 배치를 제공하지만, 때로는 한 방향으로만 아이템 정렬이 필요한 경우도 있습니다.
그리드 레인 레이아웃과 명시적으로 배치한 아이템을 함께 사용하면 이러한 1차원 그리드 레이아웃을 만들 수 있습니다.
1.2. 값 정의
이 명세는 CSS 속성 정의 규약을 [CSS2]에서 따르며, 값 정의 구문은 [CSS-VALUES-3]을 사용합니다. 이 명세에서 정의되지 않은 값 타입은 CSS 값 및 단위 [CSS-VALUES-3]에 정의됩니다. 다른 CSS 모듈과 결합해 이러한 값 타입의 정의가 확장될 수 있습니다.
명세 내 각 속성별 값 이외에도, 이 명세에 정의된 모든 속성은 CSS 전역 키워드도 값으로 허용합니다. 가독성을 위해 명시적으로 반복하지 않습니다.
2. 그리드 레인 레이아웃 모델
그리드 레인 레이아웃은 그리드 레이아웃과 같이 한 축(그리드 축)에 사전 정의된 트랙에 아이템을 배치하고, 다른 축(스태킹 축)에는 플렉스 레이아웃 처럼 자유롭게 배치합니다. 그리드 레이아웃과 비슷하지만 플렉스 레이아웃과는 달리, 그리드 레인 레이아웃의 자동 배치는 각 트랙의 길이가 최대한 비슷하도록 아이템을 분배합니다.
그리드 아이템은 블록화되며, 이는 일반 그리드 컨테이너와 동일합니다.
다른 명세에서 달리 지정하지 않는 한, 모든 CSS 속성은 일반 그리드 컨테이너와 동일하게 동작합니다. 예를 들어 order 속성을 사용해 아이템의 레이아웃 순서를 다르게 지정할 수 있습니다.
참고: 서브그리드 아이템도 지원되지만, 서브그리드 적용은 그리드 축에서만 발생합니다. 자세한 내용은 § 3.2 서브그리드를 참고하세요.
그리드 레인 컨테이너는 그리드 컨테이너로, 내부 콘텐츠가 그리드 레인 레이아웃에 참여합니다. 그리드 레인 컨테이너는, 스태킹 축이 블록 축일 때 컬럼 트랙을, 스태킹 축이 인라인 축이면 행 트랙을 생성합니다.
| 컬럼 레인 |
grid-template-columns: 1fr 2fr 3fr; |
|
|---|---|---|
| 행 레인 |
grid-template-rows: 1fr 2fr 3fr; |
|
2.1. 순서 변경 및 접근성
그리드 레인 레이아웃은 일반적으로 앞 방향으로 진행되지만 (최소한 한 축에서 다음 아이템을 현재 아이템의 끝쪽에 배치하여, 자연스러운 “읽기 순서”와 일치시킴), 인라인 혹은 블록 축 중 임의로 뒤쪽으로 전환될 수 있습니다. 간단한 경우 item-tolerance 속성은 자동 배치된 아이템 레이아웃 시 스태킹 축 내에서 작은 크기 차이로 인한 되돌아감(backtracking) 현상을 줄이는 데 도움이 될 수 있습니다. 하지만 자동 배치와 명시적 배치 또는 아이템 늘이기(span)를 혼합하면 어느 정도의 되돌아감이 발생할 수 있습니다.
< 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 { display : grid - lanes ; grid-template-columns : repeat ( 5 , auto ); } . item { height : 50 px ; } . item . wide { grid-column : span 3 ; } . item . tall { height : 90 px ; } </ style >
저자는 이러한 가능성을 염두에 두고, 되돌아감이 최소화된 레이아웃을 설계하여 포커스 및 읽기 순서를 더 쉽게 따를 수 있도록 해야 합니다. 또는, 아이템이 본질적으로 순서가 없다면, reading-flow 속성을 사용해 사용자 에이전트가 읽기 및 선형 내비게이션용으로 아이템 순서를 재정렬할 수 있도록 하세요.
아니면 여기서 자동 배치된 아이템에 대해 순서 변경이 기본 동작이 되어야 할까요?
-
item-tolerance에 적절한 값을 사용하는 것, 즉 비슷한 크기의 트랙 간 불필요한 분리를 피할 만큼 충분히 크지만, 의미 있는 차이가 무시되지 않을 정도로 값이 너무 크지 않게 조정
-
관련된 아이템들을 그룹화하는 데 도움이 되도록 명시적 배치를 사용하는 것, 아이템의 자연스러운 순서를 방해하는 방식으로 사용하지 말 것
-
그리드 축의 span 사이즈 혼합과 스태킹 축에서 아이템 크기 차이가 큰 것을 피할 것, 이렇게 하면 아이템이 순서에서 이탈될 수 있음(위 예시 참고)
그리드 레이아웃 및 플렉스 레이아웃과 마찬가지로 저자들은 order 속성을 사용해 아이템의 순서를 재조정할 수 있습니다. 같은 주의사항이 적용됩니다. 자세한 내용은 CSS Grid Layout 2 § 4 순서 변경 및 접근성 와 CSS Display 4 § 3.1 순서 변경 및 접근성을 참고하세요.
2.2. 그리드 레인 레이아웃 설정
| 이름: | display |
|---|---|
| 새 값: | grid-lanes | inline-grid-lanes |
- grid-lanes
- 이 값은 요소가 블록 수준 그리드 레인 컨테이너 박스를 생성하도록 합니다.
- inline-grid-lanes
- 이 값은 요소가 인라인 수준 그리드 레인 컨테이너 박스를 생성하도록 합니다.
그리드 레인 컨테이너가 그리드 축에서 서브그리드가 아닌 경우 독립적 형식 맥락을 설정합니다.
2.3. 그리드 레인 배치 방향 지정
그리드 레인 컨테이너의 방향, 즉 그리드 축이 인라인 축(열을 구성)인지 블록 축(행을 구성)인지 는 추후 결정 속성에 의해 결정됩니다.
이 속성의 초기값은 normal이며, 이것은 grid-template-* 속성들로부터 방향을 결정합니다:
-
grid-template-columns가 none 이고 grid-template-rows가 none이 아닐 때, 그리드 컨테이너의 블록 축이 그리드 축이 됩니다 (행을 구성).
.container {
display: grid-lanes;
grid-template-columns: 100px 200px;
}
아래 코드는 가로로 확장되는 2행(“벽돌담 스타일”) 그리드 레인 컨테이너 를 만듭니다:
.container {
display: grid-lanes;
grid-template-rows: 100px 200px;
}
여기서 grid-auto-flow를 재사용할지 (그리고 그 값의 의미) 또는 grid-lanes-direction과 같은 새 속성을 정의할지 결정해야 합니다. [Issue #12803]
3. 그리드 레인 트랙 명세
그리드 축에서는, 트랙 지정에 대해 그리드 레이아웃의 모든 기능을 사용할 수 있습니다:
-
트랙 크기, 라인 이름, 그리고 영역은 그리드 레인 컨테이너의 그리드 축에 지정할 수 있으며, 이는 그리드 레이아웃에서와 동일합니다.
하지만, 자동 배치된 항목들은 최종적으로 배치되는 트랙뿐만 아니라 모든 트랙의 크기 결정에 기여합니다; § 3.4 그리드 축 트랙 크기 결정을 참고하세요.
참고: 자동 배치 항목은 배치되는 동시에 레이아웃되어야 하므로, 각 트랙이 얼마나 “가득 찼는지”를 알 수 있습니다 (따라서 다음 자동 배치 항목이 어느 트랙에 들어갈지 결정할 수 있습니다); 그러므로 트랙 자체는 이미 명확한 크기를 가져야 하며, 그래야 항목들도 레이아웃 시 사용 가능한 공간을 알 수 있습니다.
3.1. 그리드 레인 트랙 템플릿 선언: grid-template-* 속성
grid-template-* 및 grid-auto-rows/grid-auto-columns 속성 (및 그 축약형) 은 그리드 축의 그리드 레인 컨테이너에 적용되며 일반 그리드 컨테이너에서와 동일하게 트랙을 생성합니다. (스태킹 축에서는 무시됩니다.)
3.1.1. 고유 트랙과 repeat()
레벨 3에서는 repeat() 표기법이 확장되어 최소 트랙 크기 함수와 최대 트랙 크기 함수 중 어느 것도 확정적이지 않아도 반복이 가능해집니다. 즉, <auto-repeat>의 구문이 다음과 같이 완화됩니다:
<auto-repeat> = repeat( [ auto-fill | auto-fit ] , [ <line-names>? <track-size> ]+ <line-names>? )
반복 횟수 결정을 위해, 해당 트랙의 가상 크기를 계산합니다 (CSS Grid Layout 2 § 12.4 트랙 크기 초기화 참고) 그리고 CSS Grid Layout 2 § 12.5 고유 트랙 크기 해석에 따라 § 3.4 그리드 축 트랙 크기 조정과 다음 가정으로 고유 트랙 크기를 해석합니다:
-
명시적 아이템 배치를 무시 (즉, 모든 아이템이 자동 위치라고 가정)
-
어떠한 트랙도 축소(collapse)하지 않음
-
각 아이템의 모든 가능한 자동 배치를 모두 반영하도록 반복 트랙 리스트를 확장, 즉 리스트를
2 + (최대 span - 2)/(repeat() 내 트랙 개수)번 반복하고, 아래로 내림
repeat() 리스트 내 각 트랙의 가상 크기는 해당 인덱스에 대응하는 여러 트랙 중 가장 큰 값이 됩니다.
이런 방식이 그리드 레이아웃에도 적용되어야 할까요, 아니면 반복 한 번만 수행해야 할까요? 적용된다면 어떻게? [이슈 #10915]
참고: 이 단순화된 레이아웃 휴리스틱은 “충분히 괜찮은” 결과와 함께 빠르고 일관적으로 하기 위해 정의되어 있습니다. 아이템이 몇 번 반복되는지 알기 전에 배치가 무시되어야 개념을 일관성 있게 유지할 수 있습니다; 반복 개수를 알기 전에는 명시적으로 위치를 지정한 아이템조차 실제로 어느 트랙에서 끝날지 알 수 없습니다.
기술적으로 명시적 배치가 반복 내부에 진입하거나 교차하지 않는다면 반복 해석 전에 배치를 알 수 있습니다. 위 알고리즘에 이를 반영해야 할까요? 예를 들어 auto repeat(auto-fill, ...) auto에서 1번 또는 -1번 라인에 명시적으로 아이템을 넣는다면, 해당 트랙에만 영향을 주도록 할 수도 있습니다(모든 트랙에 들어간다고 가정하지 말고).
3.2. 서브그리드
서브그리딩은 중첩된 그리드 레인 컨테이너(및 그리드 컨테이너)가 트랙 크기를 공유할 수 있게 해줍니다. 부모의 해당 축이 그리드 축인 경우, 서브그리드된 축은 부모 컨테이너에서 그리드 컨테이너에 대해 지정된 대로 상속됩니다; 부모의 해당 축이 스태킹 축인 경우, 서브그리드된 축 역시 스태킹 축 역할을 합니다.
만약 이것이 레인 방향과 충돌하거나 양 축 모두 스태킹되는 결과가 된다면 어떻게 될까요?
그리드 레인 레이아웃에서는, 자동 배치된 서브그리드는 부모 그리드로부터 어떤 라인 이름도 상속하지 않습니다, 왜냐하면 이것은 아이템의 배치가 레이아웃 결과에 의존하게 만들기 때문입니다; 그러나 서브그리드의 트랙은 여전히 부모의 트랙에 일반적으로 맞춰집니다.
<style> .grid{ display : inline-grid-lanes; 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() 표기법에 대해 새로운 키워드 및 grid-lanes 전용 동작을 도입합니다.
3.3.1. repeat(auto-fit)
그리드 레인 컨테이너(일반 그리드 컨테이너와 마찬가지로)에서 auto-fit은 auto-fill처럼 동작하지만, 비어 있는 트랙은 축소됩니다. 하지만, 배치가 트랙 크기 결정 이후에 일어나기 때문에, 그리드 레인 컨테이너는 트랙이 점유될지 여부를 판별하기 위해 휴리스틱을 사용합니다:
-
명시적으로 배치된 아이템이 있는 트랙은 모두 사용된 것으로 간주합니다.
-
자동 배치 아이템의 span 합을 N이라 할 때, 사용되지 않은 트랙 중 N번째까지는 모두 사용된 것으로 간주합니다.
이 휴리스틱으로 사용되지 않은 것으로 간주된 auto-fit 반복으로 만들어진 모든 트랙은 “비어 있음”으로 간주되며 축소됩니다. 축소된 그리드 트랙에는 자동 배치 아이템을 배치할 수 없습니다.
참고: 자동 배치 아이템이 auto-fill을 사용할 때 트랙에 배치된 경우, auto-fit을 쓴다면 축소될 수 있습니다. span이 1보다 큰 자동 배치 아이템이 명시 배치 아이템과 섞여 있고 이로 인해 자동 배치 아이템이 들어갈 수 없는 작은 빈 공간이 생긴 경우에 해당합니다.
3.4. 그리드 축 트랙 크기 조정
트랙 크기 조정은 CSS Grid와 동일하게 동작하나, 고유 크기에 기여하는 아이템을 고려할 때만 다릅니다:
-
해당 트랙에 명시적으로 배치된 모든 아이템이 기여하며,
-
자동 그리드 위치를 가진 모든 아이템도 기여합니다 (실제로 해당 트랙에 배치되는지와 관계없이).
-
A, B, C 아이템은 명시적 위치가 없다고 가정합니다.
-
D 아이템은 첫 번째 컬럼에 명시적으로 배치되어 있습니다.
이 경우, A, B, C, D 모두가 첫 번째 컬럼 크기 산정에 기여하며, 두 번째 컬럼에는 A, B, C만(그리고 D는 제외) 기여합니다.
자동 그리드 위치를 가진 span 아이템의 경우, 모든 가능한 시작 위치에 놓인 것으로 보고 각각에 맞게 기여합니다.
-
1번 그리드 라인에서, 처음 두 트랙에 각각 110px을 기여.
-
2번 그리드 라인에서, 두 번째 트랙에 120px을 기여.
-
3번 그리드 라인에서, 네 번째 트랙에 120px을 기여.
-
4번 그리드 라인에서, 네 번째와 다섯 번째 트랙에 각각 110px을 기여.
참고: 이 알고리즘은 각 트랙이 최종적으로 배치되는 모든 항목을 수용할 수 있을 만큼 충분히 크도록 보장하며, 배치와 트랙 크기 결정 간의 순환 의존성을 만들지 않습니다. 그러나 항목 크기의 변동에 따라 트랙이 필요 이상으로 커질 수 있습니다. 모든 항목이 그리드 축에 명시적으로 배치되거나 모든 항목의 크기가 동일할 때(또는 영역을 차지하는 항목의 경우 해당 크기의 배수일 때)에만 정확하게 맞는 것이 보장됩니다.
3.4.1. 서브그리드 아이템 기여
정규 그리드 컨테이너 또는 그리드 레인 컨테이너의 트랙 크기를 지정할 때, 그리드 레인 서브그리드는 자동 그리드 위치를 가진 항목에 대해 특별한 처리를 합니다:
-
이러한 아이템은 해당 그리드 레인 서브그리드에서 span 가능한 모든 그리드 트랙에 배치하는 것으로 간주합니다. (서브그리드에 명확한 그리드 위치가 있으면 해당 트랙만; 자동 그리드 위치면 부모 그리드의 모든 트랙)
-
이러한 아이템은 가상으로 배치될 수 있는 각 엣지에서 가장 큰 margin/border/padding 값을 받습니다. 만약 아이템이 전체 서브그리드를 span한다면 양쪽 모두를 적용합니다. (CSS Grid Layout §9 참고)
3.4.2. 최적화된 트랙 크기 조정
아래와 같이 동일한 span 크기와 배치를 가진 아이템을 하나의 가상 아이템으로 집계함으로써 트랙 크기 산정을 최적화할 수 있습니다:
-
모든 그리드 아이템을 다음 속성에 따라 아이템 그룹으로 분리합니다:
-
아이템의 span
-
아이템의 배치 (즉, 아이템이 배치될 수 있는 트랙)
-
아이템의 기준선 공유 그룹
참고: 예를 들어, span이 2이고 두 번째 트랙에 배치된 아이템과 span이 2이나 자동 그리드 위치를 가지는 아이템은 다른 그룹에 속합니다.
-
-
각 아이템 그룹마다
해당 그룹의 모든 아이템 중에서
고유 크기 기여값이 최대인 것으로 가상
그리드 아이템을 합성합니다.
아이템들이 기준선 정렬을 적용한다면, 해당 가상 그리드 아이템의 기준선을 모든 아이템을 하나의 가상 그리드 트랙에 배치해 공유 기준선과 shim을 산출하는 방식으로 정합니다. 이에 따라 그룹의 고유 크기 기여값도 증가시킵니다.
- 각 가상 그리드 항목의 가상 복사본을 그리드 축 트랙의 항목이 차지할 수 있는 모든 위치에 배치하고, 그 항목들과 함께 트랙 크기 결정 알고리즘을 실행하세요. 이때 나온 트랙 크기가 그리드 레인 컨테이너의 트랙 크기가 됩니다.
참고: 이 최적화는 위 트랙 크기 산정 설명과 동일한 결과를 주어야 합니다; 그렇지 않다면 오류이니 CSSWG에 보고해 주세요.
4. 그리드 레인 항목 배치
그리드 축에서, 항목들은 익숙한 그리드 배치 속성 문법을 사용하여 트랙에 명시적으로 배치하고 트랙을 걸칠 수 있습니다. 그러나 자동 배치의 경우 § 4.4 그리드 레인 레이아웃 및 배치 알고리즘을 사용하여, 자동 그리드 위치를 가진 각 항목을 사용할 수 있는 “가장 짧은” 트랙에 배치합니다.
.container{ grid-template-columns : repeat ( 3 , auto); } .container > :nth-child( 2 ) { /* auto-placed, but spanning. */ grid-column: span2 ; } .container > :nth-child( 3 ) { /* manually placed */ grid-column:3 ; } /* all other children are auto-placed */
4.1. 그리드 축 아이템 배치 지정: grid-column-* 및 grid-row-* 속성
grid-column-* 및 grid-row-* 속성(및 그 숏핸드)은 아이템의 그리드 축에 적용되며, 일반 그리드 레이아웃과 동일하게 배치를 설정합니다.
4.2. 배치 정밀도: item-tolerance 속성
| 이름: | item-tolerance |
|---|---|
| 값: | normal | <길이-퍼센트> | infinite |
| 초기값: | normal |
| 적용 대상: | 그리드 레인 컨테이너 |
| 상속: | 아니오 |
| 퍼센트: | 그리드 축 콘텐츠 박스 크기에 대해 상대적임 (그리드 레인 컨테이너) |
| 계산된 값: | 계산된 <길이-퍼센트> 값 |
| 정식 순서: | 문법대로 |
| 애니메이션 타입: | 길이로 간주 |
그리드 레인 컨테이너는 각 그리드 항목을 현재 가장 적게 채워진 그리드 트랙에 배치하여 채웁니다. 여러 트랙의 채움 정도가 같다면, 항목을 순서대로 채우는 것이 보기 좋습니다. 그러나 트랙의 높이 차이가 매우 약간만 다를 때, 순서대로 채우지 않으면 보기 부자연스러울 수 있습니다. 높이 차이가 의미 있게 느껴지지 않기 때문입니다.
item-tolerance 속성은 “같은 높이”라고 간주하여 순서대로 채우도록 만드는 기준값(임계치)을 지정합니다.
- <길이-퍼센트>
-
동률 임계값을 그리드 레인 컨테이너에 대해 지정합니다. 지정된 거리 이내면 배치 위치가 동등하게 좋다고("동률") 간주합니다. 최단 위치로부터 일정 거리 설정입니다.
참고: 초기값은 "작은" 거리(1em)로, "충분히 비슷함"을 나타내기에 적합할 것입니다.
- normal
-
사용값이 그리드 레인 레이아웃에서는 1em이고, 다른 레이아웃 모드에서는 0이 됩니다.
- infinite
-
무한한 동률 임계값으로 지정합니다. 항목이 트랙의 길이와 상관없이 무조건 순서대로 분포되도록 합니다.
참고: 이 값은 연속된 항목이 스태킹 축에서 극적으로 다른 위치에 배치될 수 있으므로, 독자 입장에서 혼란스러울 수 있습니다. 초기값(
1em)이 너무 작으면infinite대신10em또는50vh와 같이 더 큰 값을 사용해 보세요.
기본 허용값(1em) 기준으로는 첫 번째와 네 번째 열이 "동률"로 간주되어, 첫 번째 열에 배치됩니다.
만약 허용값이 0px이면 동률은 없으므로, 네 번째 열만 배치 대상이 됩니다.
CSSWG는 이 속성에 더 나은 이름을 제안받고 있습니다. [Issue #10884]
참고: 이 속성은 향후 플렉스 레이아웃에도 적용될 예정이며, 어떻게 동작할지에 대해서는 토론을 참고하세요.
4.3. 조밀한 배치: dense 키워드
그리드 레이아웃에서 grid-auto-flow: dense는 그리드 항목 배치 알고리즘 동안 되돌아가기를 허용합니다. dense 키워드도 그리드 레인 배치 알고리즘 중에 유사하게 되돌아가기를 허용합니다. 하지만 그리드 레인 레이아웃에서는 항목 배치와 크기 결정이 서로 얽혀 있으므로, 항목은 해당 슬롯의 트랙이 항목이 기본적으로 배치되는 트랙의 사용 크기와 일치하는 경우에만 호환되는 빈 슬롯으로 되돌아갈 수 있습니다.
참고: 이 제한은 항목을 여러 번 레이아웃하는 것을 방지합니다.
4.4. 그리드 레인 레이아웃 및 배치 알고리즘
그리드 축의 각 트랙에 대해, 0으로 초기화된 실행 위치를 저장합니다. 또한 최초 라인을 가리키는 자동 배치 커서도 유지합니다.
order-modified 문서 순서의 각 항목에 대해:
-
항목이 확정 그리드 위치를 그리드 축에 가지면, 그 위치를 사용합니다.
그렇지 않으면, 다음 하위 단계로 그리드 축에 배치합니다:
- 그리드 축의 암시적 그리드의 첫 번째 라인부터 시작하여, 항목이 이 라인에 배치될 경우 걸치는 트랙들의 실행 위치 최대값을 구하고, 이 위치를 max_pos라 합니다.
- 항목이 그리드 내에 더 이상 맞지 않을 때까지, 각 연속된 라인에 대해 위 단계를 반복합니다.
- max_pos가 가장 작은 라인과, 해당 max_pos 범위 안에서 동률 임계값에 속하는 모든 라인을 가능한 라인들로 둡니다.
- 자동 배치 커서보다 크거나 같은 가능한 라인들 중 첫 번째 라인을 항목의 그리드 축 위치로 선택합니다. 없다면 첫 번째 라인을 선택합니다.
- 자동 배치 커서를 항목의 마지막 라인으로 갱신합니다.
- 항목을 그리드 축 트랙의, 본 항목이 걸치는 트랙들 중 실행 위치의 최대값에 배치합니다.
-
항목의 포함 블록 크기를 계산한 뒤, 항목을 레이아웃합니다.
해당 그리드 축 트랙들의 실행 위치를
max_pos + 외부 크기 + grid-gap으로 설정합니다.이때 박스의 외부 크기는 0 미만으로 내려가지 않습니다.
참고: 즉, 박스가 매우 큰 음수 마진을 갖더라도 여기서 음수 크기로 간주되지 않습니다. 트랙의 실행 위치는 절대 감소하지 않아, 음수 크기의 박스로 인해 향후 (정상 크기의) 다른 항목들이 이전 항목과 겹치는 상황이 생기지 않습니다.
-
그리드 레인
컨테이너가 dense 배치를 쓸 때
배치 과정에서 건너뛴(가령 걸치기 때문 등으로 생긴) 공간이 있고,
현 항목이 지금 사이즈로 그 공간에 예전단계에서 배치될 수 있으며,
걸치는 트랙들의 총 사용 크기가 지금 배치된 트랙들과 동일하다면,
해당 공간들 중 가장 위에 위치에 항목을 배치합니다.
여러 곳이 동률(동률 임계값 이내)이라면,
그중 start 방향에 가장 가까운 곳에 둡니다.
자동 배치 커서와
실행 위치를,
본 항목 배치 전 값으로 되돌립니다.
참고: 시각적으로 이전 공백에 침범하는 항목(음수 마진, position: relative, 변환 등)은 그 공간의 크기를 바꾸지 않습니다. 이후 항목이 그 공백에 배치될 수 있어 결과적으로 겹칠 수 있습니다.
참고: Dense 배치는 백필될 때 자동 배치 커서를 무시하고, 배치 후에도 갱신하지 않습니다. 하지만 백필할만한 공간이 없으면 dense를 쓰지 않는 경우와 완전히 동일하게 배치합니다.
참고: 이 알고리즘은 항목이 가능한 한 가장 위에 배치되도록 트랙을 고릅니다. 동률이 있을 경우, 가장 빠른 트랙을 선택하며, 가능하다면 바로 직전에 배치된 항목 다음으로 진행되도록(동률이어도 "앞으로만 나아가게") 합니다.
4.4.1. 포함 블록
컨테이닝 블록은 그리드 항목이 그리드 레인 레이아웃에 참여할 때 그리드 영역이 그리드 축에서 형성되고, 그리드 컨테이너의 콘텐츠 박스가 스태킹 축에서 형성됩니다.
4.4.2. 배치와 쓰기 모드
참고: 그리드 레이아웃과 마찬가지로, 그리드 레인 레이아웃 및 배치는 글쓰기 모드에 민감합니다. 예를 들어, direction: rtl의 경우, 인라인 축이 그리드 축이건 스태킹 축이건, 항목이 왼쪽에서 오른쪽이 아닌, 오른쪽에서 왼쪽으로 배치됩니다.
<style> .grid{ display : inline-grid-lanes; 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{ display : inline-grid-lanes; 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 크기)는 그리드 컨테이너가 스태킹 축에 있을 때, 해당 축에서 그리드 레인 컨테이너가 max-content 제약 (min-content 제약)으로 크기가 지정될 때 스태킹 영역의 크기와 같습니다. 스태킹 영역은 각 트랙의 첫 항목들 중에서 가장 시작점에 가까운 외부 경계와 각 트랙 마지막 항목들 중에서 가장 마지막 외부 경계 사이의 범위를 의미합니다.
<style> .grid{ display : inline-grid-lanes; 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. 정렬과 간격
6.1. 거터: row-gap, column-gap, 그리고 gap 속성
거터는 row-gap과 column-gap 속성(그리고 이들의 gap 축약형)을 사용하여 양 축 모두에서 지원됩니다. 그리드 축에서는 일반 그리드 컨테이너와 동일하게 동작합니다; CSS Grid Layout 2 § 11. 정렬과 간격을 참고하세요. 스태킹 축에서는 각 인접 항목 쌍의 마진 박스 사이에 gap이 적용됩니다. 마진은 어느 축에서도 병합되지 않습니다.
6.2. 그리드 축 정렬: align-content/justify-content, align-self/justify-self, 그리고 align-items/justify-items 속성
그리드 축에서는 box 정렬 속성이 일반 그리드 컨테이너와 동일하게 동작합니다. CSS Grid Layout 2 § 11. 정렬과 간격 및 CSS Box Alignment Level 3을 참고하세요.
6.3. 스태킹 축 콘텐츠 분포: align-content/justify-content 속성
스태킹 축에서는 콘텐츠 분포가 전체 콘텐츠에 적용되며, 블록 컨테이너에서의 동작과 유사합니다. 좀 더 정확하게는, 정렬 대상이 스태킹 영역이 됩니다.
참고: 이 속성들은 스태킹 축에서 항상 하나의 정렬 대상만 가집니다. 따라서 align-content / justify-content 값은 start, center, end, baseline alignment로 귀결됩니다. (normal과 stretch의 동작은 start와 동일하며, 분산 정렬 값은 대체 정렬로 동작합니다.) 그리드 항목이 그리드 컨테이너의 콘텐츠 박스를 스태킹 축에서 넘칠 경우, 스태킹 영역이 그리드 컨테이너의 콘텐츠 박스보다 더 커지게 됩니다.
6.4. 스태킹 축 자기 정렬: align-self/justify-self, 그리고 align-items/justify-items 속성
스태킹 축에서는 자기 정렬 속성이 레이아웃에서 gap에 인접한 항목, 즉 그리드 트랙에서 걸치는 항목 직전 또는 마지막 항목으로 배치된 경우에만 적용됩니다. 정렬 대상은 해당 항목의 마진 박스이고, 정렬 컨테이너는 그 박스와 인접 gap을 포함합니다.
자기 정렬 속성이 스태킹 축에서 이렇게 동작하는 것이 적절한가요? [Issue #10275]
6.5. 기준선 정렬
기준선 정렬은 그리드 축 트랙에서 일반 그리드 컨테이너와 동일하게 동작하며, 그리드 컨테이너의 기준선은 해당 축의 일반 그리드 컨테이너와 동일하게 결정됩니다.
기준선 정렬은 스태킹 축에서는 지원되지 않습니다. 이 축에서 그리드 컨테이너의 첫 번째 기준선 집합은 각 트랙의 첫 항목 중 가장 높은 정렬 기준선에서, 마지막 기준선 집합은 각 트랙 마지막 항목 중 가장 낮은 정렬 기준선에서 생성됩니다.
첫 번째 행에서 기준선 정렬을 지원할 수도 있습니다. 도입할까요?
7. 조각화
7.1. 스태킹 축 조각화
그리드 축의 각 트랙은 스태킹 축에서 독립적으로 조각화됩니다. 그리드 항목이 조각화되거나, 그 전에/후에 강제 분할이 있다면, 그리드 축에서 해당 항목이 걸치는 트랙의 실행 위치는 조각화 컨테이너(fragmentainer) 크기로 설정되어, 이후에는 해당 트랙에 항목이 더 배치되지 않게 됩니다. 여러 조각(fragment)으로 나뉜 항목은 모든 조각에서 그리드 축 상의 배치 위치를 유지합니다. 반면, 밀려난 그리드 항목은 다음 그리드 컨테이너 조각에서 다시 배치됩니다. 모든 항목이 배치되거나 새로운 조각으로 밀려날 때까지 배치가 계속됩니다.
7.2. 그리드 축 조각화
그리드 축의 그리드 레인 컨테이너에서도 조각화가 지원됩니다. 이 경우, 조각화는 일반 그리드 컨테이너에서처럼 동작하지만, 항목을 어느 그리드 축 트랙에 배치할지는 조각화가 일어나기 전에 별도로 결정하는 단계가 있습니다.
8. 절대 위치 지정
그리드 정렬 절대 위치 하위 항목은 그리드 레인 컨테이너에서 일반 그리드 컨테이너와 마찬가지로 지원됩니다. 다만, 스태킹 축에서는 배치용으로 두 개의 라인(그리고 추가적으로 auto 라인)이 있습니다:
스태킹 축에서 정적 위치를 정의하면 유용할 수 있습니다. 이 위치가 해당 시점의 그리드 축 트랙의 최대(또는 최소?) 실행 위치, 혹은 바로 앞 항목의 끝이 될 수 있을까요?
9. 우아한 강등(Graceful Degradation)
일반적으로, 그리드 레인 디자인은 그리드 레이아웃은 지원하지만 그리드 레인 레이아웃은 지원하지 않는 UA(사용자 에이전트)에서도 상당히 자연스럽게 강등됩니다.
이를 보여주는 예시가 있습니다.
display : grid; display : grid-lanes; /* grid lanes layout을 지원하지 않는 UA에서는 무시됨 */ grid-template-columns:150 px 100 px 50 px ;
이 코드는 세 개의 열을 가진 레이아웃을 만드나, UA에서 블록 축의 그리드 레인 레이아웃을 지원하지 않을 경우, "갭이 더 많아진" 형태가 됩니다. 그리드 레인 지원이 있는 UA에서 어떻게 나타나는지 비교 예시입니다:
부록 A: 일반 레이아웃 항목 흐름 제어: item-* 속성
이 절은 여러 display 유형에 영향을 주므로 [css-display-4] 등 다른 스펙으로 이동할 수 있습니다. 또한 이것이 좋은 아이디어인지에 대해서도 논의 중입니다.
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 | row/column 속성이 제어하는 축의 반대 방향에서 항목을 래핑할지 여부, 그리고 래핑 시 앞뒤/뒤앞 순서로 채울지 제어 | flex-wrap | 이 레벨의 grid-auto-flow에서 도입 |
| item-pack | item-pack | normal | dense || balance | 항목이 각 트랙에 어떻게 "채워지는지" 정함 | grid-auto-flow | |
| item-tolerance | item-tolerance | normal | <길이-퍼센트> | infinite | 배치 결정에서 "여유(slack)"의 범위를 레이아웃 별로 지정함 |
CSSWG는 이 속성의 명칭 및 결합 방식을 논의 중입니다. [Issue #11480]
항목 흐름 주축: item-track/item-direction
| 이름: | item-direction, item-track |
|---|---|
| 값: | auto | row | column | row-reverse | column-reverse |
| 초기값: | auto |
| 적용 대상: | flex 컨테이너, 그리드 컨테이너, 그리드 레인 컨테이너 |
| 상속: | 아니오 |
| 퍼센트: | N/A |
| 계산값: | 명시된 대로 |
| 정식 순서: | 문법 순서대로 |
| 애니메이션 타입: | 불연속(discrete) |
이 속성은 항목이 행에 배치될지, 열에 배치될지와 트랙 안에서 앞→뒤/뒤→앞 순서를 제어합니다.
이 속성에는 두 가지 논의점이 있습니다: a) 명칭을 어떻게 할 것인가 b) 배치의 주요 방향(primary axis)을 나타내는지, 아니면 항목이 놓이는 트랙 방향(primary track axis)을 나타내는지. 즉, 이 속성이 정의하는 주축(primary axis)이 주 배치축인지 주 트랙축인지. flex 레이아웃과 그리드 레이아웃에서는 동일하나, 그리드 레인 레이아웃에서는 배치 방향과 트랙 방향이 다릅니다. 최신 논의 참고. [Issue #11480]
- auto
-
레이아웃 모드에 따라 row 또는 column으로 계산됩니다:
-
그리드 레인 컨테이너에서는, grid-template-rows가 none이 아니고, grid-template-columns가 none일 때 row로 계산, 그 외에는 column으로 계산합니다.
- row
-
트랙 기준 옵션 행(즉, 인라인 축 방향)으로 배치됨을 의미합니다. 항목은 해당 행을 앞→뒤로 채웁니다.
흐름 기준 옵션 항목이 주로 행(즉, 인라인 축 방향)으로 배치됨을 뜻합니다. flex 레이아웃에서는 flex 행 라인, 그리드 레인 레이아웃에서는 열 그리드 트랙을 생성합니다.
- column
-
트랙 기준 옵션 열(즉, 블록 축 방향)으로 배치됨을 의미합니다. 항목은 해당 열을 앞→뒤로 채웁니다.
흐름 기준 옵션 항목이 주로 열(즉, 블록 축 방향)로 채워짐을 의미합니다. flex 레이아웃에서는 flex 열 라인, 그리드 레인 레이아웃에서는 행 그리드 트랙을 생성합니다.
- 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 레이아웃에서는 단일 행 flex 컨테이너를, 그리드 레이아웃에서는 필요시 주 배치축에 암시적 트랙을 생성합니다.
- wrap
-
주 배치축 공간이 부족할 때 항목을 감쌉니다. flex 레이아웃에서는 멀티라인 flex 컨테이너를, 그리드 레이아웃에서는 명시적 트랙이 부족시 주 배치축 다음 행/열로 넘어갑니다.
- normal
-
주 트랙축의 반대방향에 start→end 순서로 배치합니다.
flex 레이아웃 및 그리드 레이아웃에서는 새 트랙(행/열 플렉스 라인, 그리드 트랙)의 생기는 방향을 제어합니다.
그리드 레인 레이아웃에서는 트랙 기준 문법일 때 동률 트랙 중 채워질 순서를 제어, 흐름 기준 문법일 때 해당 트랙 내 항목 채움 방향 제어
- reverse
-
주 트랙축의 반대방향에 end→start 순서로 배치합니다.
- 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
-
이전 공간이 남았지만 너무 커서 앞에서 건너뛰었던 자리에 항목을 되돌려 채웁니다. (이전 항목이 너무 커서 해당 공간에는 들어갈 수 없었던 경우 등)
예를 들어, flex 레이아웃에서는 아직 공간이 남아 있는 이전 행에 항목을 배치할 수 있게 합니다.
- balance
-
flex 레이아웃에서는 각 행(마지막 행 포함) 내용을 균형 있게 분배하며, text-wrap-style: balance와 유사합니다.
항목 배치 단축 속성: item-flow 단축형
| 이름: | item-flow |
|---|---|
| 값: | <'item-direction'> || <'item-wrap'> || <'item-pack'> || <'item-tolerance'> |
| 초기값: | 개별 속성 참조 |
| 적용 대상: | 개별 속성 참조 |
| 상속: | 개별 속성 참조 |
| 퍼센트: | 개별 속성 참조 |
| 계산값: | 개별 속성 참조 |
| 애니메이션 타입: | 개별 속성 참조 |
| 정식 순서: | 문법 순서대로 |
이 단축 속성은 모든 item-* 장황 속성을 한 번에 지정합니다.
10. 감사의 글
Cameron McCormack에게 감사드립니다. 그는 메이슨리 레이아웃 설명 문서를 작성하여 CSSWG에 발표했고, 그 문서에서 배경 챕터를 가져왔습니다. 그리고 Mats Palmgren에게도 감사드립니다. 그는 이 명세의 초기 버전을 개발했습니다. 또한 이 기능의 초기 제안에 피드백을 주신 모든 분들께도 감사드립니다.
11. 보안 고려사항
이 명세는 레이아웃 명세이므로, CSS 레이아웃이 일반적으로 노출하는 것 외에 새로운 보안 고려사항을 추가하지 않습니다.
12. 개인정보 보호 고려사항
이 명세는 레이아웃 명세이므로, CSS 레이아웃이 일반적으로 노출하는 것 외에 새로운 개인정보 보호 고려사항을 추가하지 않습니다.
변경 사항
레벨 2 이후 추가 사항
다음 기능들이 Level 2 이후에 추가되었습니다:
- 그리드 레인 레이아웃 추가
- repeat(auto-fill) 및 repeat(auto-fit)이 무한(track sizing function)을 허용하도록 확장 (이슈 9321, 이슈 12899)
- item-flow 속성과 그 롱핸드 속성들이, 항목 정렬 및 배치에 대한 일반 제어로 추가됨 자세한 내용은 부록 A: 일반 레이아웃 항목 흐름 제어: item-* 속성 참조 (이슈 11480)
최근 변경
다음 변경 사항들은 2025년 9월 17일자 작업 초안 이후 적용되었습니다:
-
새로운 inner display 타입 grid-lanes를 정의해 그리드 레인 레이아웃을 설정하며, 사양의 용어도 이에 맞게 수정함 (이슈 12022)
-
무한 track sizing function와 함께 사용할 때 repeat(auto-fill) 및 repeat(auto-fit)의 휴리스틱을 조정함 (이슈 12899)
또한 이전 변경 사항도 참고하세요.