Flexible Box도 훌륭하지만 비교적 단순한 1차원 레이아웃을 위하며, 좀 더 복잡한 레이아웃을 위해 우리는 CSS Grid를 사용할 수 있습니다.
즉, grid
는 flex
와 달리 1차원이 아닌 2차원을 활용하여 레이아웃 구조를 만들 수 있습니다.
Container와 Items 별로 수많은 속성과 값들이 존재하므로 링크를 참고하여 간단하게 실습하며 속성들의 기본값을 이해하며 예상치 못한 레이아웃 문제에 대비할 수 있도록 깊게 다루어 봅시다.
Grid Container에만 지정 가능한 속성들에 대하여 알아봅시다.
grid를 block과 lnline요소의 특성을 가지도록 설정하는 속성으로 값으로 grid
와 inline-grid
가 존재합니다.
명시적으로 행의 크기를 정의합니다.
fr
(fraction, 공간 비율) 단위를 사용할 수 있습니다.repeat()
함수를 사용할 수 있습니다..container {
display: grid;
grid-template-rows: 1행크기 2행크기 ...;
grid-template-rows: [선이름] 1행크기 [선이름] 2행크기 [선이름] ...;
}
/* 각 행의 크기를 정의합니다. */
.container {
grid-template-rows: 100px 200px;
}
/* 동시에 각 라인의 이름도 정의할 수 있습니다. */
.container {
grid-template-rows: [first] 100px [second] 200px [third];
}
/* 라인에 중복된 이름을 지정할 수 있습니다. */
.container {
grid-template-rows: [row1-start] 100px [row1-end row2-start] 200px [row2-end];
}
/* repeat 함수 사용 가능 */
.container {
width: 400px;
display: grid;
grid-template-rows: repeat(3, 100px); /* 3개의 행이 100px 높이 */
grid-template-columns: repeat(3, 1fr); /* 3개의 열이 전체 너비의 1의 공간 비율 너비*/
}
명시적 열의 크기를 정의합니다. 사용법은 grid-template-rows와 같습니다.
fr
(fraction, 공간 비율) 단위를 사용할 수 있습니다.repeat()
함수를 사용할 수 있습니다..container {
display: grid;
grid-template-columns: 1열크기 2열크기 ...;
grid-template-columns: [선이름] 1열크기 [선이름] 2열크기 [선이름] ...;
}
지정된 그리드 영역 이름(grid-area
)을 참조해 그리드 템플릿을 생성합니다.
grid-area
는 Grid Container가 아닌 Grid Item에 적용하는 속성입니다.
.container {
display: grid;
grid-template-rows: repeat(3, 100px);
grid-template-columns: repeat(3, 1fr);
grid-template-areas:
"header header header"
"main main aside"
"footer footer footer";
}
header { grid-area: header; }
main { grid-area: main; }
aside { grid-area: aside; }
footer { grid-area: footer; }
각 행과 행, 열과 열 사이의 간격(Gutter)을 지정합니다.
.container {
border: 4px solid;
display: grid;
grid-template-rows: repeat(4, 100px);
grid-template-columns: repeat(3, 1fr);
grid-template-areas:
'header header header'
'main main aside'
'. . aside'
'footer footer footer';
grid-gap: 10px 40px; /* 행과 행의 간격, 열과 열의 간격 */
}
.container > * {
border: 2px solid;
}
.container header {
grid-area: header;
}
.container main {
grid-area: main;
}
.container aside {
grid-area: aside;
}
.container footer {
grid-area: footer;
}
암시적 행(Track)의 크기를 정의합니다.
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
.container {
width: 300px;
height: 200px;
display: grid;
grid-template-rows: 100px 100px; /* 명시적 2개 행 정의 */
grid-template-columns: 150px 150px; /* 명시적 2개 열 정의 */
grid-auto-rows: 100px; /* 그 외(암시적) 행의 크기 정의 */
}
.item:nth-child(3) {
grid-row: 3 / 4;
}
암시적 열(Track)의 크기를 정의합니다.
.container {
width: 300px;
height: 200px;
display: grid;
grid-template-rows: 100px 100px;
grid-template-columns: 150px 150px;
grid-auto-rows: 100px;
grid-auto-columns: 100px;
}
.item:nth-child(3) {
grid-row: 3 / 4;
grid-column: 3 / 4;
}
배치하지 않은 아이템(Item)을 어떤 방식의 ‘자동 배치 알고리즘’으로 처리할지 정의합니다.
다음은 row
와 row dense
에 대한 예제입니다.
.container {
display: grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(3, 1fr);
grid-auto-flow: row || row dense || dense;
}
.item:nth-child(2) {
grid-column: span 3;
}
다음은 column
과 column dense
에 대한 예제입니다.
.container {
display: grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(3, 1fr);
grid-auto-flow: column || column dense;
}
.item:nth-child(1) {
grid-column: 2 / span 2;
}
.item:nth-child(2) {
grid-column: span 2;
}
그리드 콘텐츠(Contents)를 수평(행 축) 정렬하며 반드시 그리드 콘텐츠의 가로 너비가 그리드 컨테이너(Container)보다 작아야 합니다 (빈 공간이 존재해야 한다)
.container {
width: 450px;
height: 450px;
display: grid;
grid-template-rows: repeat(3, 100px);
grid-template-columns: repeat(3, 100px);
justify-content: <justify-content>; /* 전체 요소들의 크기 합이 컨테이너의 영역을 벗어나지 않으므로 적용 가능 */
}
그리드 콘텐츠(Contents)를 수직(열 축) 정렬하며 그리드 콘텐츠의 세로 너비가 그리드 컨테이너(Container)보다 작아야 합니다.
그리드 아이템(Items)들을 수평(행 축) 정렬하며, 그리드 아이템의 가로 너비가 자신이 속한 그리드 열(Track)의 크기보다 작아야 합니다.
.container {
width: 450px;
height: 450px;
display: grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(3, 1fr);
justify-items: <justify-items>;
}
그리드 아이템(Items)들을 수직(열 축) 정렬하며, 그리드 아이템의 세로 너비가 자신이 속한 그리드 행(Track)의 크기보다 작아야 합니다.
.container {
width: 450px;
height: 450px;
display: grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(3, 1fr);
align-items: <align-items>;
}
Grid Items에만 지정 가능한 속성들에 대하여 알아봅시다.
그리드 아이템(Item)을 배치하기 위해 그리드 선(Line)의 ‘시작 위치’와 ‘끝 위치’를 지정하며 ‘숫자’를 지정하거나, ‘선 이름’을 지정하거나, span
키워드를 사용합니다.
.container {
display: grid;
grid-template-rows: repeat(2, 1fr);
grid-template-columns: repeat(3, 1fr);
}
.item:nth-child(1) {
grid-row-start: 1;
grid-row-end: 3;
grid-column-start: 2;
grid-column-end: 4;
}
/* span 키워드와 ‘숫자’를 조합하면 ‘숫자’만큼 라인을 확장하는(+) 개념 */
.item:nth-child(1) {
/* Row 1번에서 3번(1+2=3)까지 */
grid-row-start: 1;
grid-row-end: span 2;
/* Column 2번에서 3번(2+1=3)까지 */
grid-column-start: 2;
/* grid-column-end: span 1; (생략) */
}
/* 단축 속성으로 표현 가능 */
.item {
grid-row: <grid-row-start> / <grid-row-end>;
}
.item {
grid-column: <grid-column-start> / <grid-column-end>;
}
/* 같은 표현 */
.item {
grid-row-start: 1;
grid-row-end: 2;
}
.item {
grid-row: 1 / 2;
}
/* 같은 표현 */
.item {
grid-row-start: 2;
grid-row-end: span 3;
}
.item {
grid-row: 2 / span 3;
}
.item {
grid-row: 2 / 5;
}
/* 같은 표현 */
.item {
grid-column-start: 2;
grid-column-end: -1;
}
.item {
/* Column 2번에서 끝(-1번)까지 */
grid-column: 2 / -1;
}
단일 그리드 아이템(Item)을 수평(행 축) 정렬하며 그리드 아이템의 가로 너비가 자신이 속한 그리드 열(Track)의 크기보다 작아야 합니다.
.container {
display: grid;
grid-template-rows: repeat(2, 1fr);
grid-template-columns: repeat(2, 1fr);
}
.item:nth-child(1) { justify-self: start; }
.item:nth-child(2) { justify-self: center; }
.item:nth-child(3) { justify-self: end; }
.item:nth-child(4) { justify-self: stretch; }
단일 그리드 아이템(Item)을 수직(열 축) 정렬하며 그리드 아이템의 세로 너비가 자신이 속한 그리드 행(Track)의 크기보다 작아야 합니다.
.container {
display: grid;
grid-template-rows: repeat(2, 1fr);
grid-template-columns: repeat(2, 1fr);
}
.item:nth-child(1) { align-self: start; }
.item:nth-child(2) { align-self: center; }
.item:nth-child(3) { align-self: end; }
.item:nth-child(4) { align-self: stretch; }
그리드 아이템이 자동 배치되는 순서를 변경할 수 있으며 숫자가 작을수록 앞서 배치됩니다.
.container {
display: grid;
grid-template-rows: repeat(2, 1fr);
grid-template-columns: repeat(3, 1fr);
}
.item:nth-child(1) { order: 1; }
.item:nth-child(3) { order: 5; }
.item:nth-child(5) { order: -1; }
z-index
속성을 이용해 아이템이 쌓이는 순서를 변경할 수 있습니다.
.item:nth-child(1) {
grid-area: 1 / 1 / 2 / 3;
}
.item:nth-child(2) {
grid-area: 1 / 2 / 3 / 3;
z-index: 1;
}
.item:nth-child(3) {
grid-area: 2 / 2 / 3 / 4;
}