# CSS Grid 사용 가이드

## Grid vs Flexbox

Grid와 Flexbox는 모던 레이아웃 모듈의 대표 주자로 다양한 레이아웃을 구현할 수 있습니다. 하지만 각각 특성이 있어 전문으로 하는 분야가 달라 상황에 따라 적합한 방법을 사용하면 됩니다.&#x20;

Grid 레이아웃은 박스 및 콘텐츠의 크기와 위치를 제어 할 수 있는 강력한 기능을 가진 새로운 레이아웃 모델입니다. X 또는 Y 중 하나의 축을 통해 요소를 배치하는 [Flexbox](https://www.w3.org/TR/css-flexbox-1/)와 달리, Grid는 2차원 축을 모두 사용해 요소를 배치할 수 있어 보다 강력합니다.

![Flexbox 레이아웃](https://3440753900-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LH1dN99ZXtZTFG_0JKV%2F-LH5jUEzOmxZUnS9Icq1%2F-LH5kFFAK9tf4zwc1v5P%2Fimage.png?alt=media\&token=0ce914a6-f77e-472c-a1a1-0d50e4cee8d4)

![Grid 레이아웃](https://3440753900-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LH1dN99ZXtZTFG_0JKV%2F-LH5jUEzOmxZUnS9Icq1%2F-LH5kJM_kwTZRUbeGDb_%2Fimage.png?alt=media\&token=7b65e84c-0a30-479c-8804-bb8ecec4035c)

Grid 레이아웃은 요소를 그리드에 자유롭게 배치 할 수 있기 때문에 HTML 마크업 순서와 상관 없이 시각적으로 레이아웃 구조를 변형하는데 제약이 없습니다. 뿐만 아니라 [미디어 쿼리](https://www.w3.org/TR/css3-mediaqueries/)와 그리드를 함께 사용하면 다양한 디바이스에 최적화된 인터페이스를 사용자에게 제공할 수 있습니다.

Grid는 2차원 방향으로 배치 또는 정렬이 가능하고, 레이아웃에 대한 하향식(Top-Down) 접근법을 사용합니다. 요소를 명시적으로 겹치거나, 강력한 스패닝(Span) 기능을 제공합니다.

Flexbox는 축(Axis) 내의 공간 분배에 중점을 두고 레이아웃에 대한 간단한 상향식 접근법을 사용합니다. 컨텐츠 크기 기반의 줄 바꿈 시스템을 사용하여 보조 축을 제어하고 기본 마크업 계층을 사용하여 보다 복잡한 레이아웃을 작성합니다.&#x20;

2가지 방법 모두 CSS 제작자에게 가치 있고 상호 보완적인 도구가 될 것으로 기대됩니다.

## 등장 배경 <a href="#background" id="background"></a>

웹 사이트가 단순한 문서에서 복잡한 인터랙션을 수행하는 애플리케이션으로 발전함에 따라, 문서 레이아웃 기술만으로 애플리케이션 레이아웃을 구현하기 어려워졌습니다. 기존의 레이아웃 기술을 총 동원하여 애플리케이션 레이아웃을 구현했으나, 다양한 문제가 발생했고, 많은 애플리케이션이 제약된 레이아웃 방법을 선택하는 것으로 타협했습니다.

그리드 레이아웃은 이러한 문제를 해결하기 위해 고안되었습니다. 레이아웃에 사용 가능한 공간을 행과 열에 맞춰 배치할 수 있는 메커니즘을 제공합니다. 제작자는 애플리케이션의 빌딩 블록 요소를 정의된 [그리드 영역](../css-grid-term#grid-area)에 정확하게 배치하거나, 크기를 설정할 수 있습니다.&#x20;

![행/열에 맞춰 레이아웃 된 애플리케이션 인터페이스](https://3440753900-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LH1dN99ZXtZTFG_0JKV%2F-LH5jUEzOmxZUnS9Icq1%2F-LH5qP0QWatIzMX18lpG%2Fimage.png?alt=media\&token=5241a997-f582-4252-ba08-a3885f6f98d5)

### 자유로운 배치 / 크기 조정 <a href="#align-growth" id="align-growth"></a>

그리드 레이아웃은 웹 페이지 내의 요소를 스마트하게 크기 조정하는데 사용할 수 있습니다. 아래 그림은 게임 제목(Game Title), 통계(Stats) 게임 보드(Board), 점수(Score) 및 컨트롤(Controls) 영역으로 레이아웃을 구성하는 5가지 컴포넌트가 있는 게임 애플리케이션 인터페이스입니다. 제작자는 게임 인터페이스를 구성하는 공간을 다음과 같이 나눕니다.

![게임 인터페이스](https://3440753900-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LH1dN99ZXtZTFG_0JKV%2F-LH5jUEzOmxZUnS9Icq1%2F-LH5y9BzpdsxZhil7Al8%2Fimage.png?alt=media\&token=7270f76a-c819-4d5f-9cc3-9ee5da7cd005)

* "통계" 영역은 항상 "게임 제목" 바로 아래에 나타납니다.
* "게임 보드"는 "통계" 및 "제목" 오른쪽에 나타납니다.
* "게임 제목"의 상단과 "게임 보드"는 항상 정렬 되어야 합니다.
* "게임 보드"의 하단과 "통계" 영역의 하단은 게임이 최소 높이에 도달하면 정렬됩니다. \
  다른 모든 경우에 "게임 보드"는 사용할 수 있는 모든 공간을 활용하기 위해 늘어납니다.
* "컨트롤"은 게임 보드 중앙에 위치합니다.
* "스코어" 영역의 상단은 "컨트롤" 영역의 상단에 정렬됩니다.
* "점수" 영역은 "통계" 영역 아래에 있습니다.
* "점수" 영역은 "통계" 영역 아래의 "컨트롤"에 정렬됩니다.

요구 조건에 따라 그리드를 사용해 게임 인터페이스를 레이아웃 하는 코드를 살펴보세요.

{% tabs %}
{% tab title="game-grid-layout.html" %}
```markup
<div id="grid">
  <div id="title"> 게임 제목 </div>
  <div id="board"> 게임 보드 </div>
  <div id="controls"> 컨트롤 </div>
  <div id="stats"> 통계 </div>
  <div id="score"> 점수 </div>
</div>
```
{% endtab %}

{% tab title="game-grid-layout.css" %}
```css
#grid {
  display: grid;
  grid-template-rows: auto 1fr auto;
  grid-template-columns: auto 1fr;
}

#title    { 
  grid-column: 1; 
  grid-row: 1; 
}
#score    { 
  grid-column: 1; 
  grid-row: 3; 
}
#stats    { 
  grid-column: 1; 
  grid-row: 2; 
  align-self: start; 
}
#board    { 
  grid-column: 2; 
  grid-row: 1 / span 2; 
}
#controls { 
  grid-column: 2; 
  grid-row: 3; 
  justify-self: center; 
}
```
{% endtab %}
{% endtabs %}

### 다양한 기기에서의 화면 최적화 <a href="#adapt-view" id="adapt-view"></a>

이전 예제를 계속 하면서 게임 인터페이스가 다양한 크기의 화면에서 최적화 되길 원합니다. 뿐만 아니라 세로 또는 가로 방향으로 화면을 볼 때 컴포넌트 레이아웃을 적절하게 배치할 수 있어야 합니다 (아래 그림 참고). 그리드 레이아웃과 미디어 쿼리를 결합 함으로써 제작자는 동일한 시맨틱 마크업으로 코드의 순서와 상관없이 요소의 레이아웃을 재배치 하여 각 방향의 화면 모드에서 원하는 레이아웃을 얻을 수 있습니다.

![수직 모드(Portrait) 화면의 게임 인터페이스](https://3440753900-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LH1dN99ZXtZTFG_0JKV%2F-LH5jUEzOmxZUnS9Icq1%2F-LH5zmGOKn71JGbsdv4X%2Fimage.png?alt=media\&token=e79151ce-c10b-4def-9edd-5a3bf6129032)

![수평 모드(Landscape) 화면의 게임 인터페이스](https://3440753900-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LH1dN99ZXtZTFG_0JKV%2F-LH5jUEzOmxZUnS9Icq1%2F-LH5zoBvNhX7PuzMPli6%2Fimage.png?alt=media\&token=01af0dbf-69b1-4134-963d-78a2cc1ba3c0)

요구 조건에 따라 그리드를 사용해 게임 인터페이스를 다양한 화면에서 레이아웃 하는 코드는 다음과 같습니다.

{% tabs %}
{% tab title="adapt-game-grid-layout.html" %}
```markup
<div id="grid">
  <div id="title"> 게임 제목 </div>
  <div id="board"> 게임 보드 </div>
  <div id="controls"> 컨트롤 </div>
  <div id="stats"> 통계 </div>
  <div id="score"> 점수 </div>
</div>
```
{% endtab %}

{% tab title="adapt-game-grid-layout.css" %}
```css
#grid {
  display: grid;
  grid-template-columns: auto 1fr;
}
@media (orientation: portrait) {
  #grid {
    grid-template-rows: auto auto 1fr auto;
    grid-template-areas: "title stats"
                         "score stats"
                         "board board"
                         "ctrls ctrls";
  }
}

@media (orientation: landscape) {
  #grid {
    grid-template-rows: auto 1fr auto;
    grid-template-areas: "title board"
                         "stats board"
                         "score ctrls";
  }
}

#title    { grid-area: title }
#score    { grid-area: score }
#stats    { grid-area: stats }
#board    { grid-area: board }
#controls { grid-area: ctrls }
```
{% endtab %}
{% endtabs %}

{% hint style="info" %}
그리드 레이아웃의 순서 재배치 기능은 시각적인 화면 렌더링 만 영향을 주며, 소스 순서에 따라 음성 출력 및 내비게이션 합니다. 이를 통해 제작자는 시멘틱 마크업을 그대로 유지한 채, 다양한 화면에서 최적화 된 레이아웃을 제작할 수 있습니다.
{% endhint %}

{% hint style="warning" %}
그리드 요소 레이아웃 및 재배치를 사용할 경우, 마크업 순서대로 화면에 그려지는 것이 아니기에 문서 접근성 문제가 발생할 수 있음을 주의해야 합니다.
{% endhint %}
