본문 바로가기

grid

1. 2차원 레이아웃 grid

flex가 1차원 레이아웃을 담당했다면 2차원 레이아웃은 grid가 담당합니다. 행과 열을 동시에 제어할 수 있어 복잡한 레이아웃을 쉽게 만들 수 있습니다.

Grid design system

CSS Grid는 웹 디자인의 grid design system에서 가져온 개념을 구체화한 기술입니다. Grid design system은 화면을 콘텐츠로 채우기 전에 위치를 정할 가이드를 먼저 그려서 어디에 무엇을 어떤 크기로 배치할지 설계하는 개념입니다.

출처: 머터리얼 디자인 시스템

Grid design system에 대해 더 자세히 알아보려면 다음 링크를 참조하세요.

Material DesignUsing Grids in Interface Designs

이러한 Grid design system의 개념을 바탕으로 CSS Grid가 개발되었으며, 이를 통해 웹 개발자들은 더욱 효율적이고 일관된 레이아웃을 구현할 수 있게 되었습니다.

1.1 그리드의 기본 구성 요소

그리드를 구성하는 기본적인 용어를 알아보겠습니다. 2차원 레이아웃인 만큼 조금 복잡해 보일 수 있지만, 실습을 통해 쉽게 이해할 수 있습니다.

1.1.1 그리드 컨테이너와 그리드 셀

  • 그리드 컨테이너: 그리드의 가장 바깥 영역입니다.
  • 그리드 셀: 그리드의 한 칸을 의미합니다. 이는 개념적인 정의입니다.

1.1.2 그리드 아이템

그리드 아이템은 그리드 컨테이너의 자식 요소들을 말합니다.

1.1.3 그리드 트랙

그리드 트랙은 그리드의 행(row) 또는 열(column)을 의미합니다.

1.1.4 그리드 라인과 그리드 넘버

  • 그리드 라인: 그리드 셀을 구분하는 선입니다.
  • 그리드 넘버: 그리드 라인의 각 번호를 말합니다.

1.1.5 그리드 갭

그리드 갭은 그리드 셀 사이의 간격(gutter)을 의미합니다.

1.1.6 그리드 에어리어

그리드 에어리어는 그리드 셀의 집합을 말합니다.

이러한 기본 구성 요소들을 이해하면 그리드 레이아웃을 더 효과적으로 사용할 수 있습니다. 각 요소들이 어떻게 상호작용하는지 알면, 복잡한 레이아웃도 쉽게 구현할 수 있습니다.

1.2 grid를 적용하는 방법

grid 레이아웃을 시작하는 기본 속성입니다. 부모 요소에 display: grid를 설정하면 자식 요소들이 grid item이 되어 grid 레이아웃을 사용할 수 있습니다. 부모 요소를 grid-container 자식 요소를 grid-item 이라고 부릅니다. 이를 통해 자식들을 배치하고 정렬할 수 있습니다.

.container {
  display: grid;
}

1.3 grid-container에 사용하는 속성

1.3.1 행 방향과 열 방향 설정

grid-template-columns는 열방향 그리드 트랙의 사이즈를 설정하고 grid-template-rows 행방향 그리드 트랙의 사이즈를 설정합니다. 픽셀, 백분율, fr 단위를 사용할 수 있습니다. fr은 분수(fraction)의 의미로 컨테이너를 분할해줍니다. 아래 예제를 통해 다양하게 실습해보세요.

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
</div>
.container {
  display: grid;
  width: 200px;
  height: 200px;
  /*
  grid-template-columns: 100px 100px 100px;
  grid-template-rows: 200px 100px;
  */
  grid-template-columns: 1fr 1fr 1fr;
  /*
  grid-template-rows: 2fr 1fr;
  */
}

div {
  border: 1px solid black;
  text-align: center;
}

이렇게 생성된 grid는 아래와 같이 개발자도구에서 확인할 수 있습니다. 다른 서비스에서 grid가 어떻게 사용되는지 확인해보세요.

1분코딩

fr 단위

  • fraction: 분수
  • 컨테이너를 분할해줍니다.
  • grid 컨테이너 안에서 트랙의 비율을 지정해주는 유연한 길이 단위입니다
  • 1fr 1fr 1fr은 1:1:1 의 비율을 의미합니다.
.container {
  grid-template-columns: 1fr 2fr 1fr;
}

1.3.2 함수

1. repeat()

row 혹은 column 방향으로 grid-track 의 사이즈를 좀 더 간단한 형태로 표현하도록 도와주는 CSS 함수입니다. 함수에 전달하는 첫번째 인자는 반복 횟수(repeat count), 두번째 인자는 반복할 값입니다.

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
</div>
.container {
  display: grid;
  width: 300px;
  height: 300px;
  /* grid-template-columns: 1fr 1fr 1fr; */
  grid-template-columns: repeat(3, 1fr);
}

div {
  border: 1px solid black;
  text-align: center;
}

아래와 같이 반복되는 구조도 만들 수 있습니다.

/* grid-template-columns: 1fr 2fr 1fr 2fr; */
grid-template-columns: repeat(2, 1fr 2fr);

2. minmax()

minmax() 함수는 그리드에서 최소와 최대 사이의 범위를 설정하는 함수입니다. 두 개의 인자를 가지며, 첫 번째는 최소값, 두 번째는 최대값을 의미합니다. 설정된 값은 최소값보다 크거나 같고, 최대값보다 작거나 같은 크기 범위를 정의합니다.

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
</div>
.container {
  display: grid;
  grid-template-columns: repeat(3, minmax(100px, 1fr));
  gap: 10px;
}

.item {
  background-color: #3498db;
  color: white;
  padding: 20px;
  text-align: center;
}

이 예제에서 각 열은 최소 100px 너비를 유지하면서 사용 가능한 공간에 따라 최대 1fr까지 유연하게 늘어나며, 브라우저 창 크기 조절 시 이러한 변화를 관찰할 수 있습니다.

1.3.3 auto-fill과 auto-fit

auto-fill과 auto-fit은 repeat() 함수와 함께 사용되는 키워드로, 컨테이너의 너비에 따라 자동으로 그리드 컬럼을 배치할 때 사용합니다.

auto-fill

가능한 많은 컬럼을 만들어냅니다. 컨테이너에 빈 공간이 남을 수 있습니다.

.container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}

auto-fit

auto-fill과 유사하지만, 그리드 컨테이너 내부에 공간이 남을 경우 그 공간을 각 셀들이 나눠 갖습니다.

.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
<div class="container auto-fill">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

<div class="container auto-fit">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
.container {
  display: grid;
  gap: 10px;
  margin-bottom: 20px;
}

.auto-fill {
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}

.auto-fit {
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}

.item {
  background-color: #3498db;
  color: white;
  padding: 20px;
  text-align: center;
}

이 예제에서 브라우저 창의 크기를 조절해보면 auto-fill과 auto-fit의 차이를 확인할 수 있습니다. auto-fill은 빈 열을 만들어내는 반면, auto-fit은 남은 공간을 채우기 위해 열을 늘립니다. 이러한 기능들을 활용하면 반응형 그리드 레이아웃을 더욱 유연하게 만들 수 있습니다.

1.3.4 gap

셀과 셀사이의 간격을 설정할 때 사용 할 수 있는 속성입니다. 복잡한 레이아웃 안에서 마진 대신 편리하게 간격을 설정할 수 있습니다. grid-gap은 gap으로 사용할 수 있습니다. 이 속성은 flex와 동일한 속성입니다.

.container {
  gap: 10px; /* 모든 간격 */
  gap: 10px 20px; /* 행 간격 열 간격 */
}

gap은 익스플로러 미지원 속성입니다.

1.3.5 수평과 수직 정렬

그리드 컨테이너와 아이템의 정렬을 위해 다음과 같은 속성들을 사용할 수 있습니다.

align-content와 justify-content

이 속성들은 그리드 아이템을 트랙 단위로 정렬합니다.

  • align-content: 그리드 아이템을 수직(열) 방향으로 정렬합니다.
  • justify-content: 그리드 아이템을 수평(행) 방향으로 정렬합니다.
.container {
  align-content: stretch | center | start | end | space-around | space-between |
    space-evenly;
  justify-content: stretch | center | start | end | space-around | space-between
    | space-evenly;
}

주의

이 속성들을 사용하려면 그리드 아이템의 전체 크기가 그리드 컨테이너보다 작아야 합니다. 즉, 컨테이너 내에 여유 공간이 있어야 합니다.

align-items와 justify-items

  • align-items: 각 셀 내에서 그리드 아이템을 수직(열) 방향으로 정렬합니다.
  • justify-items: 각 셀 내에서 그리드 아이템을 수평(행) 방향으로 정렬합니다.

이 속성들은 각 그리드 셀 내에서 아이템을 정렬합니다.

.container {
  align-items: stretch | center | start | end;
  justify-items: stretch | center | start | end;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
</div>
.container {
  display: grid;
  grid-template-columns: repeat(2, 100px);
  grid-template-rows: repeat(2, 100px);
  gap: 10px;
  height: 300px;
  background-color: #f0f0f0;

  /* 정렬 속성 설정 */
  justify-content: center;
  align-content: center;
  justify-items: center;
  align-items: center;
}

.item {
  width: 50px;
  height: 50px;
  background-color: #3498db;
  color: white;
  display: flex;
  justify-content: center;
  align-items: center;
}

이 예제에서는 그리드 아이템들이 컨테이너의 중앙에 위치하며, 각 셀 내에서도 중앙에 정렬됩니다. 속성 값을 변경해보면서 정렬 방식의 차이를 확인해보세요.

1.4 그리드 아이템 속성

그리드 아이템에 적용할 수 있는 다양한 속성들이 있습니다. 이를 통해 개별 아이템의 위치와 크기, 정렬 등을 세밀하게 제어할 수 있습니다.

1.4.1 grid-area와 관련 속성들

grid-area는 그리드 아이템의 위치와 크기를 지정하는 단축 속성입니다.

/* 각각의 값은 그리드 라인의 번호를 의미합니다. */
grid-row-start: 1;
grid-row-end: 2;
grid-column-start: 1;
grid-column-end: 4;

/* row-start, column-start의 축약입니다. */
grid-row: 1/2;
grid-column: 1/4;

/* grid-row-start는 첫 번째 값, 
	grid-column-start는 두 번째 값, 
	grid-row-end는 세 번째 값, 
	grid-column-end는 네 번째 값으로 설정됩니다. */
grid-area: 1/1/2/4;

/* span 은 셀을 의미합니다. span 3은 셀 세개를 의미합니다. */
grid-area: 1/1/1 / span 3;

span

행과 열을 병합할때 span 키워드를 사용합니다(테이블에서는 colspan, rowspan 이 있습니다) 그리드에서는 span이라는 키워드를 사용할 수 있습니다. span의 사전적 의미는 '한 뼘', '~을 채우다' 의 의미를 가지고 있습니다.

<div class="container">
  <div class="item item1">1</div>
  <div class="item item2">2</div>
  <div class="item item3">3</div>
  <div class="item item4">4</div>
</div>
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
  gap: 10px;
}

.item {
  background-color: #3498db;
  color: white;
  display: flex;
  justify-content: center;
  align-items: center;
}

.item1 {
  grid-area: 1 / 1 / 3 / 3;
}

.item2 {
  grid-column: 3;
  grid-row: 1 / 3;
}

.item3 {
  grid-area: 3 / 1 / 4 / span 2;
}

1.4.2 grid-template-areas와 grid-area

grid-template-areas로 영역을 정의하고, grid-area로 아이템을 배치할 수 있습니다.

<div class="container">
  <header>Header</header>
  <nav>Nav</nav>
  <main>Main</main>
  <footer>Footer</footer>
</div>
.container {
  display: grid;
  grid-template-areas:
    'header header'
    'nav main'
    'footer footer';
  grid-template-columns: 200px 1fr;
  grid-template-rows: auto 1fr auto;
  gap: 10px;
  height: 300px;
}

header {
  grid-area: header;
  background-color: #3498db;
}
nav {
  grid-area: nav;
  background-color: #2ecc71;
}
main {
  grid-area: main;
  background-color: #e74c3c;
}
footer {
  grid-area: footer;
  background-color: #f39c12;
}

header,
nav,
main,
footer {
  color: white;
  padding: 10px;
}

1.4.3 z-index

그리드 내에서 z-index를 사용하여 아이템의 쌓임 순서를 제어할 수 있습니다.

<div class="container">
  <div class="item item1">1</div>
  <div class="item item2">2</div>
  <div class="item item3">3</div>
</div>
.container {
  display: grid;
  grid-template-columns: repeat(2, 100px);
  grid-template-rows: repeat(2, 100px);
}

.item {
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 24px;
  color: white;
}

.item1 {
  background-color: rgba(52, 152, 219, 0.8);
  grid-area: 1 / 1 / 3 / 3;
}

.item2 {
  background-color: rgba(231, 76, 60, 0.8);
  grid-area: 1 / 2 / 3 / 3;
  z-index: 1;
}

.item3 {
  background-color: rgba(46, 204, 113, 0.8);
  grid-area: 2 / 1 / 3 / 3;
}

z-index 속성을 grid 안에서도 사용할 수 있습니다.

grid 안에서는 굳이 position 속성을 사용하지 않더라도 화면에 보여지는 우선순위를 설정할 수 있습니다.

1.4.4 정렬 관련 속성

개별 그리드 아이템의 정렬을 제어하는 속성들입니다.

  • align-self: 개별 아이템의 수직(열) 정렬 (stretch, center, start, end)
  • justify-self: 개별 아이템의 수평(행) 정렬 (stretch, center, start, end)
  • place-self: align-self와 justify-self의 단축 속성

<div class="container">
  <div class="item item1">1</div>
  <div class="item item2">2</div>
  <div class="item item3">3</div>
  <div class="item item4">4</div>
</div>
.container {
  display: grid;
  grid-template-columns: repeat(2, 150px);
  grid-template-rows: repeat(2, 150px);
  gap: 10px;
  background-color: #f0f0f0;
}

.item {
  background-color: #3498db;
  color: white;
  font-size: 24px;
}

.item1 {
  align-self: start;
  justify-self: start;
}
.item2 {
  align-self: center;
  justify-self: center;
}
.item3 {
  align-self: end;
  justify-self: end;
}
.item4 {
  place-self: center end;
}

1.4.5 order

order 속성으로 아이템의 배치 순서를 지정할 수 있습니다.

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
</div>
.container {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}

.item {
  background-color: #3498db;
  color: white;
  padding: 20px;
  text-align: center;
}

.item:nth-child(1) {
  order: 4;
}
.item:nth-child(2) {
  order: 3;
}
.item:nth-child(3) {
  order: 2;
}
.item:nth-child(4) {
  order: 1;
}

1.4.6 grid (단축 속성)

grid는 여러 그리드 관련 속성을 한 번에 설정할 수 있는 단축 속성입니다.

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
</div>
.container {
  display: grid;
  grid: auto-flow dense / 40px 40px 1fr;
  gap: 10px;
  height: 200px;
}

.item {
  background-color: #3498db;
  color: white;
  padding: 10px;
  text-align: center;
}

이렇게 각 속성에 대한 예시 코드를 통해 그리드 아이템의 다양한 속성들을 실제로 어떻게 사용하는지 확인할 수 있습니다.

2. 참고링크

flexngrid Grid Garden Grids | MDN CSS-Tricks Grid 완벽 가이드
grid - HTML/CSS 에센셜 | 위니버시티