Grid 이해하기

MyeonghoonNam·2021년 9월 6일
0

Grid

Flexible Box도 훌륭하지만 비교적 단순한 1차원 레이아웃을 위하며, 좀 더 복잡한 레이아웃을 위해 우리는 CSS Grid를 사용할 수 있습니다.

즉, gridflex와 달리 1차원이 아닌 2차원을 활용하여 레이아웃 구조를 만들 수 있습니다.

Container와 Items 별로 수많은 속성과 값들이 존재하므로 링크를 참고하여 간단하게 실습하며 속성들의 기본값을 이해하며 예상치 못한 레이아웃 문제에 대비할 수 있도록 깊게 다루어 봅시다.


Grid Container 속성

Grid Container에만 지정 가능한 속성들에 대하여 알아봅시다.


display

grid를 block과 lnline요소의 특성을 가지도록 설정하는 속성으로 값으로 gridinline-grid가 존재합니다.


grid-template-rows

명시적으로 행의 크기를 정의합니다.

  • 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-columns

명시적 열의 크기를 정의합니다. 사용법은 grid-template-rows와 같습니다.

  • fr(fraction, 공간 비율) 단위를 사용할 수 있습니다.
  • repeat() 함수를 사용할 수 있습니다.
  • 동시에 라인(Line)의 이름도 정의할 수 있습니다.
.container {
  display: grid;
  grid-template-columns: 1열크기 2열크기 ...;
  grid-template-columns: [선이름] 1열크기 [선이름] 2열크기 [선이름] ...;
}

grid-template-areas

지정된 그리드 영역 이름(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; }


gap(grid-gap)

각 행과 행, 열과 열 사이의 간격(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;
}

grid-auto-rows

암시적 행(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;
}


grid-auto-columns

암시적 열(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;
}


grid-auto-flow

배치하지 않은 아이템(Item)을 어떤 방식의 ‘자동 배치 알고리즘’으로 처리할지 정의합니다.

다음은 rowrow 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;
}

다음은 columncolumn 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;
}


justify-content

그리드 콘텐츠(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>; /* 전체 요소들의 크기 합이 컨테이너의 영역을 벗어나지 않으므로 적용 가능 */
}

align-content

그리드 콘텐츠(Contents)를 수직(열 축) 정렬하며 그리드 콘텐츠의 세로 너비가 그리드 컨테이너(Container)보다 작아야 합니다.


justify-items

그리드 아이템(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>;
}

align-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 속성

Grid Items에만 지정 가능한 속성들에 대하여 알아봅시다.

grid-row-start, grid-row-end, grid-column-start, grid-column-end

그리드 아이템(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;
}

justify-self

단일 그리드 아이템(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; }

align-self

단일 그리드 아이템(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; }

order

그리드 아이템이 자동 배치되는 순서를 변경할 수 있으며 숫자가 작을수록 앞서 배치됩니다.

.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 (쌓임 순서)

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;
}


참고자료

profile
꾸준히 성장하는 개발자를 목표로 합니다.

0개의 댓글