CSS는 오랫동안 웹 페이지 레이아웃을 위한 표준이었지만, 항상 완벽하지는 않았습니다. 초기에는 table을 사용했고, 이후 float, position, inline-block으로 전환했습니다. 그러나 이러한 모든 방법은 본질적으로 '꼼수'에 가까웠으며, 수직 중앙 정렬과 같은 중요한 기능이 누락되었습니다. Flexbox의 등장은 1차원 레이아웃 문제를 어느 정도 해결했지만, 복잡한 2차원 레이아웃을 목표로 하지는 않았습니다(Flexbox와 Grid는 실제로 함께 사용하면 효과적입니다). Grid는 레이아웃 문제를 해결하기 위해 특별히 설계된 최초의 CSS 모듈이며, 웹 개발자들에게 진정한 레이아웃 솔루션을 제공합니다.
브라우저 호환성
CSS Grid 레이아웃은 현대 브라우저에서 폭넓게 지원됩니다. 대부분의 주요 브라우저는 최신 버전에서 완벽하게 호환되며, IE10과 11에서는 구버전 문법을 사용해야 하지만 점차 지원 범위를 넓히고 있습니다. 이러한 호환성 덕분에 특히 모바일 환경에서 Grid 레이아웃을 자주 사용합니다.
Grid 개념 기초
- 그리드 컨테이너(Grid Container):
display: grid가 적용된 요소로, 모든 그리드 아이템의 부모 역할을 합니다. - 그리드 아이템(Grid Item): 그리드 컨테이너의 직계 자식 요소입니다.
- 그리드 라인(Grid Line): 그리드를 구성하는 분할선입니다. 열 그리드 라인과 행 그리드 라인이 있습니다.
- 그리드 트랙(Grid Track): 인접한 두 그리드 라인 사이의 영역입니다.
- 그리드 셀(Grid Cell): 인접한 두 개의 열 그리드 라인과 두 개의 행 그리드 라인 사이의 가장 작은 단위입니다.
- 그리드 영역(Grid Area): 여러 그리드 셀로 구성된 영역입니다.
부모 요소 속성
| 속성 | 설명 |
|---|---|
display |
Grid 레이아웃을 설정합니다. |
grid-template-rows |
행의 크기와 개수를 정의합니다. |
grid-template-columns |
열의 크기와 개수를 정의합니다. |
grid-template-areas |
자식 요소의 이름을 사용하여 레이아웃을 정의합니다. |
column-gap |
열 사이의 간격을 지정합니다. |
row-gap |
행 사이의 간격을 지정합니다. |
gap |
row-gap과 column-gap의 축약형입니다. |
justify-items |
모든 셀의 내용을 가로 축(X축)으로 정렬합니다. |
align-items |
모든 셀의 내용을 세로 축(Y축)으로 정렬합니다. |
justify-content |
전체 그리드를 컨테이너의 가로 축(X축)으로 정렬합니다. |
align-content |
전체 그리드를 컨테이너의 세로 축(Y축)으로 정렬합니다. |
grid-auto-columns |
명시적으로 정의되지 않은 열의 크기를 설정합니다. |
grid-auto-rows |
명시적으로 정의되지 않은 행의 크기를 설정합니다. |
grid-auto-flow |
자동 배치되는 아이템의 흐름 방향을 제어합니다. |
Grid 레이아웃 활성화
display: grid | inline-grid | subgrid;
grid: 블록 레벨 그리드 컨테이너를 생성합니다.inline-grid: 인라인 레벨 그리드 컨테이너를 생성합니다.subgrid: 부모 그리드의 트랙 크기를 상속받습니다. (현재 브라우저 지원이 제한적입니다)
열과 행 정의
grid-template-columns와 grid-template-rows는 열과 행의 개수와 크기를 정의합니다.
/* 고정 크기, 백분율, fr 단위 혼용 */
grid-template-columns: 150px 20% 1fr 2fr;
/* 그리드 라인에 이름 부여 */
grid-template-columns: [start] 200px [mid] 200px [end] 1fr [final];
/* repeat() 함수로 반복 */
grid-template-columns: repeat(4, 100px);
/* auto-fill과 minmax()를 사용한 반응형 */
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
영역 기반 레이아웃
grid-template-areas를 사용하면 직관적인 레이아웃을 만들 수 있습니다. 각 자식 요소에 grid-area로 이름을 지정해야 합니다.
.wrapper {
display: grid;
grid-template-columns: 1fr 3fr 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
}
.header { grid-area: header; }
.nav { grid-area: nav; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
간격 설정
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
column-gap: 20px;
row-gap: 15px;
/* gap: 15px 20px; (row-gap column-gap) */
}
정렬 속성
justify-items와 align-items는 그리드 셀 내부의 콘텐츠 정렬을 제어합니다.
start: 시작 위치 정렬end: 끝 위치 정렬center: 중앙 정렬stretch: (기본값) 셀 전체를 채우도록 확장
.grid {
justify-items: center;
align-items: center;
}
justify-content와 align-content는 전체 그리드를 컨테이너 내에서 정렬합니다.
start,end,centerstretch: 그리드 아이템의 크기를 조정하여 컨테이너를 채움space-around: 각 아이템 주위에 동일한 간격space-between: 첫/마지막 아이템은 끝에 맞추고 나머지 간격은 동일space-evenly: 모든 간격이 동일
.container {
display: grid;
justify-content: space-evenly;
align-content: center;
}
자동 생성 트랙
grid-auto-rows와 grid-auto-columns는 명시적으로 정의되지 않은 트랙의 크기를 설정합니다. grid-auto-flow는 아이템이 자동 배치될 때의 흐름을 결정합니다.
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(100px, auto);
grid-auto-flow: dense; /* 빈 공간을 채우기 위해 순서를 변경 */
}
자식 요소 속성
| 속성 | 설명 |
|---|---|
grid-column-start |
아이템이 시작되는 열 그리드 라인 |
grid-column-end |
아이템이 끝나는 열 그리드 라인 |
grid-row-start |
아이템이 시작되는 행 그리드 라인 |
grid-row-end |
아이템이 끝나는 행 그리드 라인 |
grid-column |
grid-column-start와 grid-column-end의 축약형 |
grid-row |
grid-row-start와 grid-row-end의 축약형 |
grid-area |
이름 부여 또는 grid-row와 grid-column의 축약형 |
justify-self |
개별 아이템의 가로 축(X축) 정렬 |
align-self |
개별 아이템의 세로 축(Y축) 정렬 |
아이템 위치 지정
그리드 라인 번호나 이름을 사용하여 아이템의 위치를 지정할 수 있습니다.
.item {
/* 그리드 라인 번호 사용 */
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
/* 축약형 */
grid-column: 2 / 4;
grid-row: 1 / 3;
/* grid-area로 한 번에 지정 (행 시작 / 열 시작 / 행 끝 / 열 끝) */
grid-area: 1 / 2 / 3 / 4;
}
/* span 키워드 사용 */
.span-item {
grid-column: 2 / span 3; /* 2번 라인부터 3칸 차지 */
grid-row: 1 / span 2;
}
개별 아이템 정렬
justify-self와 align-self는 justify-items와 align-items와 동일한 값을 가지며, 특정 아이템에만 적용됩니다.
.special-item {
justify-self: end;
align-self: center;
}
Grid 레이아웃 예제: 반응형 갤러리
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 16px;
padding: 20px;
}
.gallery-item {
background: #f0f0f0;
border-radius: 8px;
overflow: hidden;
}
.featured-item {
grid-column: span 2;
grid-row: span 2;
}
@media (max-width: 768px) {
.gallery {
grid-template-columns: repeat(2, 1fr);
}
.featured-item {
grid-column: span 1;
grid-row: span 1;
}
}