Line-based placement with CSS Grid - CSS: Cascading Style Sheets

Line-based placement with CSS Grid
==================================

그리드 레이아웃의 기본 개념을 다룬 문서에서 라인 번호를 사용하여 그리드에 아이템을 배치하는 방법을 잠깐 살펴본 적이 있습니다. 이번 문서에서는 이 기본적 기능이 어떻게 작동하는지를 자세히 살펴보겠습니다.

그리드를 연구할 때는 번호가 매겨진 라인부터 시작하는 것이 가장 논리적일 겁니다. 왜냐하면, 그리드 레이아웃을 쓸 때마다 거기엔 항상 번호가 매겨진 라인이 있기 때문입니다. 행과 열의 각 라인에는 번호가 매겨져 있으며, 라인에 번호를 매길 때는 1번부터 시작합니다. 그리드 라인은 문서의 작성 모드를 기준으로 번호가 매겨진다는 것을 명심하십시오. 영어와 같이 왼쪽에서 오른쪽으로 읽히는 언어로 쓰인 문서에서는 1번 라인이 그리드의 맨 왼쪽에 위치합니다. 반대로 오른쪽에서 왼쪽으로 읽히는 언어의 문서에서는 1번 라인이 그리드의 맨 오른쪽에 위치하게 됩니다. 문서 작성 모드와 그리드 사이의 상호 작용에 대해서는 나중에 자세히 알아보겠습니다.

간단한 예제
------

아주 간단한 예로, 세 개의 세로 열 트랙과 세 개의 가로 행 트랙으로 구성된 그리드의 예를 들어보겠습니다. 여기엔 각 방향으로 4개의 라인이 있습니다.

그리드 컨테이너 안에는 네 개의 자식 요소가 있습니다. 이것들을 아무런 조건 없이 그대로 그리드 위에 위치시키면, 자동 배치 규칙에 따라 각 아이템은 처음에 있는 네 개의 셀 위에 놓이게 됩니다. 여기서 Firefox의 Grid Highlighter (en-US)를 사용하면 그리드의 열과 행이 어떻게 정의되어 있는지 확인하실 수 있습니다.

![Our Grid highlighted in DevTools](/ko/docs/Web/CSS/CSS_grid_layout/Grid_layout_using_line-based_placement/3_hilighted_grid.png)
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
}
```

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
  <div class="box4">Four</div>
</div>
```

라인 번호로 아이템 배치하기
---------------

아이템들을 그리드 위 어느 곳에 자리 잡게 할지 조정할 때는 라인을 기준으로 배치할 수 있습니다. 우선 아래 예제에서는 첫 번째 아이템을 그리드의 맨 왼쪽부터 시작해서 하나의 열 트랙에 자리하도록 하였습니다. 또한, 그리드 상단에 있는 첫 번째 행부터 시작해서 네 번째 행까지 확장하도록 하였습니다.

```css
.box1 {
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 1;
  grid-row-end: 4;
}
```

몇몇 아이템의 위치를 지정해주면, 그리드에 있는 나머지 다른 아이템들은 자동 배치 규칙에 따라 연달아 놓이게 됩니다. 이 규칙은 나중에 가이드에서 어떻게 작동하는지 자세히 살펴볼 예정입니다만, 그리드와 작업하시면 자리를 지정하지 않은 아이템은 그리드의 비어있는 셀에 자동 배치되는 것을 자주 목격하실 수 있습니다.

각 아이템을 개별적으로 지정해서 행과 열 트랙에 걸쳐 네 개의 아이템들을 모두 배치할 수 있습니다. 원하시면 여기에 몇몇 셀들을 그냥 비워 둘 수도 있습니다. 그리드 레이아웃의 장점 중 하나는, 비어 있는 공간으로 다른 요소가 떠올라 채워지는 것을 막기 위해 마진을 써서 밀어낼 필요가 없어서, 흰 여백이 들어간 디자인을 쉽게 구현할 수 있다는 점입니다.
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
  <div class="box4">Four</div>
</div>
```

```css
.box2 {
  grid-column-start: 3;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 3;
}
.box3 {
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 2;
}
.box4 {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 3;
  grid-row-end: 4;
}
```

`grid-column`과 `grid-row` 단축용법
------------------------------

앞의 예제에선 각 아이템을 배치하기 위해 상당히 많은 코드가 작성되었습니다. 그래서 여기엔 분명 단축용법이 있을 거란 예상을 충분히 할 수 있습니다. 실제 `grid-column-start` (en-US)와 `grid-column-end` (en-US) 프로퍼티는 `grid-column` (en-US)으로 합칠 수 있으며, `grid-row-start` (en-US)와 `grid-row-end` (en-US)는 `grid-row` (en-US) 프로퍼티로 정의할 수 있습니다.
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
  <div class="box4">Four</div>
</div>
```

```css
.box1 {
  grid-column: 1 / 2;
  grid-row: 1 / 4;
}
.box2 {
  grid-column: 3 / 4;
  grid-row: 1 / 3;
}
.box3 {
  grid-column: 2 / 3;
  grid-row: 1 / 2;
}
.box4 {
  grid-column: 2 / 4;
  grid-row: 3 / 4;
}
```

### 기본 폭(spans)

위 예제에선, 프로퍼티의 사용법을 설명하려고 모든 행과 열의 마지막 라인을 지정하였습니다. 하지만, 아이템이 오직 하나의 트랙만 차지한다면 `grid-column-end`와 `grid-row-end` 값은 생략할 수 있습니다. 그리드는 기본적으로 하나의 트랙에 걸치게 돼 있습니다. 이 말은 처음의 장황했던 예제가 다음처럼 단축될 수도 있습니다:
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
  <div class="box4">Four</div>
</div>
```

```css
.box1 {
  grid-column-start: 1;
  grid-row-start: 1;
  grid-row-end: 4;
}
.box2 {
  grid-column-start: 3;
  grid-row-start: 1;
  grid-row-end: 3;
}
.box3 {
  grid-column-start: 2;
  grid-row-start: 1;
}
.box4 {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 3;
}
```

또한, 단축용법을 사용했던 예제 중 오직 하나의 트랙에 걸쳐 있는 아이템의 경우에는 뒤로 누운 슬래쉬와 두 번째 값을 생략하고 다음처럼 정의할 수 있습니다.
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
  <div class="box4">Four</div>
</div>
```

```css
.box1 {
  grid-column: 1;
  grid-row: 1 / 4;
}
.box2 {
  grid-column: 3;
  grid-row: 1 / 3;
}
.box3 {
  grid-column: 2;
  grid-row: 1;
}
.box4 {
  grid-column: 2 / 4;
  grid-row: 3;
}
```

`grid-area` 프로퍼티
----------------

우리는 여기서 한 발 더 나가 각 영역을 단 하나의 프로퍼티인 `grid-area` (en-US)로 정의할 수도 있습니다. `grid-area` 값의 순서는 다음과 같습니다.

* grid-row-start
* grid-column-start
* grid-row-end
* grid-column-end
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
  <div class="box4">Four</div>
</div>
```

```css
.box1 {
  grid-area: 1 / 1 / 4 / 2;
}
.box2 {
  grid-area: 1 / 3 / 3 / 4;
}
.box3 {
  grid-area: 1 / 2 / 2 / 3;
}
.box4 {
  grid-area: 3 / 2 / 4 / 4;
}
```

`grid-area` 값의 순서는 약간 이상하게 보일 수도 있는데, 예를 들어 마진과 패딩을 단축용법을 써서 지정할 때의 순서와 완전 정반대입니다. 하지만, 그리드가 CSS 문서 작성 모드(CSS Writing Modes) 표준 명세서에 정의된 문서 흐름과 관련된 방향을 채용해서 사용한다는 것을 알게 되면 이해하기 쉽습니다. 차후에 그리드가 문서 작성 모드에 따라 어떻게 작용하는지 알아볼 예정입니다만, 개념상 다음과 같이 문서 흐름과 관련된 네 가지 방향이 있습니다:

* block-start
* block-end
* inline-start
* inline-end

예를 들자면, 영문으로 쓰인 문서는 왼쪽에서 오른쪽으로 읽습니다. 이 경우 block-start는 그리드 컨테이너의 맨 위쪽에 있는 가로 행 라인이 차지하고, block-end는 컨테이너의 매 마지막 행에 있는 라인에 해당합니다. inline-start는 항상 현재의 문서 작성 모드에 따라 텍스트가 써지는 시작 지점이기 때문에 맨 왼쪽에 있는 세로 열 라인이 여기에 해당하고, inline-end는 그리드의 오른쪽 마지막 끝에 있는 세로 열 라인이 됩니다.

`grid-area` 프로퍼티를 써서 그리드 영역을 지정할 땐, 우선 시작 라인인 `block-start`와 `inline-start`를 먼저 정의하고, 나중에 마지막 라인으로 `block-end`와 `inline-end`를 정의합니다. 이것은 보통 우리가 top, right, bottom 그리고 left 순서의 물리적 프로퍼티를 사용하는 데 익숙하다는 점을 생각하면 이상하게 보일 수도 있지만, 웹사이트의 문서 작성 모드가 여러 방향일 수 있다는 점을 고려하면 이해가 쉬우실 겁니다.

거꾸로 세기
------

우리는 또한 그리드의 블록(block)과 인라인(inline) 지점의 끝에서부터 거꾸로 셀 수도 있는데, 영문 문서의 경우 이것은 맨 오른쪽 세로 열 라인과 마지막 가로 행 라인이 여기에 해당합니다. 이 라인들은 `-1`로 지칭할 수 있으며, 여기서 거꾸로 셀 수도 있습니다. 그래서 끝에서 두 번째 라인은 `-2`가 됩니다. 한 가지 주의할 점은, 여기서 말하는 마지막 라인은 *명시적으로* `grid-template-columns`와 `grid-template-rows`로 정의한 그리드에 있는 마지막 라인을 가리키며, 이 바깥에 있는 *잠재적 그리드*에 추가된 행이나 열을 고려하지는 않습니다.

다음 예제에는 아이템을 배치할 때 그리드의 오른쪽과 아래에서부터 작업을 시작해서 이전에 작성했던 레이아웃을 거꾸로 뒤집어 보았습니다.
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
  <div class="box4">Four</div>
</div>
```

```css
.box1 {
  grid-column-start: -1;
  grid-column-end: -2;
  grid-row-start: -1;
  grid-row-end: -4;
}
.box2 {
  grid-column-start: -3;
  grid-column-end: -4;
  grid-row-start: -1;
  grid-row-end: -3;
}
.box3 {
  grid-column-start: -2;
  grid-column-end: -3;
  grid-row-start: -1;
  grid-row-end: -2;
}
.box4 {
  grid-column-start: -2;
  grid-column-end: -4;
  grid-row-start: -3;
  grid-row-end: -4;
}
```

### 그리드 전체에 걸치도록 아이템 늘리기

아이템을 그리드 전체에 걸치도록 늘리려 할 때 유용한 방법으로 다음과 같이 그리드의 시작과 끝의 라인을 지정해줄 수 있습니다:

```css
.item {
  grid-column: 1 / -1;
}
```

경계 여백 혹은 간격
-----------

CSS 그리드 표준 명세서에는 `grid-column-gap` (en-US)과 `grid-row-gap` (en-US) 프로퍼티를 써서 열과 행 트랙 사이에 경계 여백을 정의해 줄 수 있는 기능이 포함되어 있습니다. 이것은 다중 칼럼 레이아웃에 있는 `column-gap` (en-US) 프로퍼티와 비슷하게 작용해서 트랙 사이의 간격을 지정합니다.

간격은 오직 그리드의 트랙 사이에서만 위치하고, 컨테이너의 위나 아래 혹은 왼쪽과 오른쪽에 공간을 추가하지 않습니다. 이전 예제에 있는 그리드 컨테이너에 여기에 소개한 프로퍼티를 사용하여 간격을 추가한 모습을 아래에서 확인하실 수 있습니다.
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
  <div class="box4">Four</div>
</div>
```

```css
.box1 {
  grid-column: 1;
  grid-row: 1 / 4;
}
.box2 {
  grid-column: 3;
  grid-row: 1 / 3;
}
.box3 {
  grid-column: 2;
  grid-row: 1;
}
.box4 {
  grid-column: 2 / 4;
  grid-row: 3;
}
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
  grid-column-gap: 20px;
  grid-row-gap: 1em;
}
```

### 그리드 간격의 단축용법

앞서 소개한 두 개의 프로퍼티 또한 단축용법인 `grid-gap` (en-US)으로 표현해 줄 수 있습니다. 만약에 `grid-gap` 값으로 하나만 지정하면, 열과 행 간격 모두에 같이 적용됩니다. 그리고 두 개의 값을 지정하면, 처음 것은 `grid-row-gap`에 사용되고 두 번째 것은 `grid-column-gap`에 사용됩니다.

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
  grid-gap: 1em 20px;
}
```

라인을 기준으로 한 아이템 배치 관점에서 보면, 이 간격은 마치 라인에 너비를 더한 것처럼 작용합니다. 특정 라인을 시작으로 배치되는 아이템은 간격 다음에 있는 지점에서부터 놓이게 되며, 간격을 차지하거나 그 안에 배치될 수 없습니다. 만약에 경계 여백이 일반 트랙처럼 작용하길 원하시면, 대신에 해당 목적의 트랙을 따로 지정해서 사용하길 바랍니다.

`span` 키워드 사용법
--------------

번호를 붙여서 시작과 마지막 라인을 지정하는 법과 더불어, 시작 라인을 지정한 후 원하는 만큼의 영역을 가로질러 확장하는 트랙의 수를 지정해서 사용하실 수도 있습니다.
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
  <div class="box4">Four</div>
</div>
```

```css
.box1 {
  grid-column: 1;
  grid-row: 1 / span 3;
}
.box2 {
  grid-column: 3;
  grid-row: 1 / span 2;
}
.box3 {
  grid-column: 2;
  grid-row: 1;
}
.box4 {
  grid-column: 2 / span 2;
  grid-row: 3;
}
```

또한, `grid-row-start`/`grid-row-end` 그리고 `grid-column-start/grid-column-end` 값에도 `span` 키워드가 쓰일 수 있습니다. 다음의 두 예제에서는 서로 같은 그리드 영역을 만듭니다. 첫 번째 예제에서는 가로 열의 시작 라인을 지정한 후에, 마지막 라인은 3개의 라인을 가로질러 위치하도록 설정하였습니다. 그래서 영역은 1번 라인부터 시작해서 3개의 라인을 가로질러 4번 라인까지 차지하게 됩니다.
```

.box1 {
    grid-column-start: 1;
    grid-row-start: 1;
    grid-row-end: span 3;
}
```

두 번째 예제에선, 아이템이 끝나는 지점에 있는 마지막 라인을 지정한 다음 시작 라인을 `span 3`으로 설정하였습니다. 이 얘기는 아이템이 지정한 마지막 가로 열 라인으로부터 위쪽으로 확장해야 한다는 뜻입니다. 이렇게 하면, 영역은 4번 라인부터 시작해서 3개의 라인을 가로질러 1번 라인까지 차지하게 됩니다.
```

.box1 {
    grid-column-start: 1;
    grid-row-start: span 3;
    grid-row-end: 4;
}
```

그리드 라인을 기준으로 아이템을 배치하는 법에 익숙해지시려면, 다양한 수의 열로 이뤄진 그리드에 아이템들을 배치하시면서 몇 가지 일반적 레이아웃을 만들어보는 여러 시도를 해보시기 바랍니다. 여기서 주의할 점은 모든 아이템의 위치를 일일이 지정하지 않았다면, 나머지 아이템들은 자동 배치 규칙에 따라 배치된다는 것을 명심하시기 바랍니다. 이런 레이아웃이 원하시는 것일 수도 있지만, 만약에 의도치 않은 곳에 아이템이 표시된다면, 해당 아이템의 위치를 지정해 주었는지 꼭 확인해 보십시오.

또한, 그리드에 배치된 아이템들은 원하시면 명확히 지정해서 서로 자리가 겹치게 할 수도 있다는 것을 잊지 마십시오. 이렇게 하면 특이하고 멋진 효과를 만들어 낼 수도 있습니다만, 만약에 시작 혹은 마지막 라인을 잘못 지정해 놓았다면, 의도치 않은 곳에서 서로 겹쳐 버리는 결과를 가져올 수도 있습니다. Firefox Grid Highlighter (en-US)는 배우시면서 매우 유용하게 사용될 수 있는데, 특히나 그리드가 상당히 복잡한 경우에는 더 그렇습니다.

1. **CSS**
2. **CSS Reference**
3. CSS 그리드 레이아웃
4. **가이드**
    1. 그리드 레이아웃의 기본 개념
    2. 다른 레이아웃 방법과의 관계
    3. 라인을 기준으로 한 아이템 배치
    4. 그리드 템플릿 영역
    5. 이름이 주어진 그리드 라인을 이용한 레이아웃
    6. Auto-placement in grid layout (en-US)
    7. Box alignment in grid layout (en-US)
    8. Grids, logical values and writing modes (en-US)
    9. CSS Grid Layout and Accessibility (en-US)
    10. CSS Grid Layout and Progressive Enhancement (en-US)
    11. Realizing common layouts using grids (en-US)
5. **프로퍼티**
    1. grid (en-US)
    2. grid-area (en-US)
    3. grid-auto-columns (en-US)
    4. grid-auto-flow (en-US)
    5. grid-auto-rows (en-US)
    6. grid-column (en-US)
    7. grid-column-end (en-US)
    8. grid-column-gap (en-US)
    9. grid-column-start (en-US)
    10. grid-gap (en-US)
    11. grid-row (en-US)
    12. grid-row-end (en-US)
    13. grid-row-gap (en-US)
    14. grid-row-start (en-US)
    15. grid-template (en-US)
    16. grid-template-areas (en-US)
    17. grid-template-columns
    18. grid-template-rows (en-US)
6. **용어집**
    1. Grid
    2. Grid lines
    3. Grid tracks
    4. Grid cell
    5. Grid areas
    6. Gutters
    7. Grid Axis
    8. Grid row (en-US)
    9. Grid column


Relationship of grid layout to other layout methods - CSS: Cascading Style Sheets

Relationship of grid layout to other layout methods
===================================================

CSS 그리드 레이아웃은 레이아웃 작업을 위한 전체 시스템 중의 일부로서, 다른 CSS 기술과 함께 어우러져 작동하도록 설계되었습니다. 이번 가이드에서는 이미 사용하고 계신 다른 기술과 그리드가 어떻게 잘 어울리는지 설명해 드리겠습니다.

그리드와 플랙스박스
----------

CSS 그리드 레이아웃과 CSS 플랙스박스(Flexbox) 레이아웃의 기본 차이점이라면, 플랙스박스는 한 줄로 된 행 *혹은* 열 방향의 레이아웃과 같이 일차원의 레이아웃을 염두에 두고 설계되었다는 점입니다. 하지만, 그리드는 행과 열 모두를 염두에 둔 2차원적 레이아웃을 고려해서 설계되었습니다. 그러나 두 기술은 몇 가지 공통된 면모를 공유하고 있어서, 이미 플랙스박스 사용법을 익히셨다면 그리드를 이해하는 데도 도움이 될 만한 둘 사이의 유사점을 목격하실 수도 있습니다.

### 1차원적 대비 2차원적 레이아웃

간단한 예를 들면, 1차원 및 2차원 레이아웃의 차이점은 확연해집니다.

첫 번째 예제에서는 플랙스박스를 써서 일련의 네모난 상자들을 배치하였습니다. 컨테이너 안에는 다섯 개의 자식 아이템이 있고, 플랙스 기준값 200픽셀을 기반으로 아이템이 늘어나거나 줄어들도록 flex 프로퍼티 값을 지정하였습니다.

또한, `flex-wrap` 프로퍼티 값으로 `wrap`을 지정해서, 만약 컨테이너 안에 있는 공간이 플랙스 기준값 너비의 아이템들을 모두 나열하지 못할 만큼 좁아진다면, 다음 행으로 줄 바꿈 하도록 하였습니다.
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
</div>
```

```css
.wrapper {
  display: flex;
  flex-wrap: wrap;
}
.wrapper > div {
  flex: 1 1 200px;
}
```

위의 그림에서 보시다시피, 두 개의 아이템이 다음 행으로 줄 바꿈 한 것을 확인하실 수 있습니다. 이 아이템들은 남은 공간을 공유하며 아래 위치한 아이템들은 위에 있는 것들과는 일렬로 정렬되지 않았습니다. 이는 플랙스 아이템이 다음 열로 감길 때, 새로운 각각의 행 (또는 세로 열 기준으로 작업할 경우 각각의 열)이 새로운 플랙스 컨테이너가 되기 때문입니다. 그래서 공간의 분배는 가로 행을 기준으로 이루어집니다.

여기서 자주 던지는 질문으로, 그러면 이런 아이템을 어떻게 하면 일렬로 정렬할 수 있을까입니다. 이럴 땐 2차원적 레이아웃 방법을 고려해 볼 수 있습니다. 아이템을 정렬할 때 행과 열을 기준으로 제어하고 싶다면, 이런 경우엔 그리드가 제격입니다.

### CSS 그리드를 이용한 동일 레이아웃 구현

다음 예제에선 그리드를 써서 똑같은 레이아웃을 만들어 보았습니다. 이번엔 `1fr` 크기로 된 세 개의 세로 열 트랙으로 이루어져 있습니다. 아이템 자체에는 아무것도 설정할 필요가 없고, 아이템들은 생성된 그리드의 각 셀에 하나씩 배치됩니다. 보시다시피 아이템들은 행과 열에 줄지어서 그리드 위에 정확히 맞추어져 있습니다. 아이템이 다섯 개인 경우, 2번째 행의 끝부분은 빈 곳으로 남게 됩니다.

```css
\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
```

그리드와 플랙스박스 둘 사이의 선택을 고민할 때 자신에게 던질 수 있는 간단한 질문으로:

* 레이아웃을 조정할 때 오직 가로 행 ***혹은*** 세로 열 만이 고려 대상이라면 – 플랙스박스를 사용하십시오
* 레아아웃을 조정할 때 가로 행과 세로 열 ***모두***를 염두에 두어야 한다면 – 그리드를 사용하십시오
### 콘텐츠 중심 혹은 레이아웃 먼저?

1차원 대비 2차원의 차이점 외에도, 레이아웃을 할 때 플랙스박스와 그리드 중에서 어떤 것을 써야 할지를 결정하는 또 다른 요인이 있습니다. 플랙스박스는 좀 더 콘텐츠에 초점이 맞춰져 있습니다. 플랙스박스의 이상적인 사용 사례는 여러 아이템을 컨테이너에 고르게 배치하려는 경우입니다. 여기서 콘텐츠의 크기가 각 아이템이 차지하는 공간을 결정합니다. 아이템이 새로운 줄로 줄 바꿈 되면, 아이템의 크기와 *해당 줄*의 사용 가능한 공간에 따라 간격이 조정됩니다.

그리드는 레이아웃을 먼저 고려하게 됩니다. CSS 그리드 레이아웃을 사용할 때는 우선 레이아웃을 작성한 다음 그 위에 아이템을 배치하거나, 자동 배치 규칙을 통해 견고하게 짜인 그리드 위에 놓인 그리드 셀에 아이템을 배치하게 됩니다. 콘텐츠의 크기에 따라 조절되는 트랙을 만들 수도 있지만, 이렇게 하면 전체 트랙을 변경하게 됩니다.

플랙스박스를 사용하면서 그 특유의 유연성 때문에 제약을 느낀다면, CSS 그리드 레이아웃을 고려해 보시는 것도 좋을 겁니다. 예를 들어 윗줄에 있는 다른 아이템과 일렬로 정렬되게 하려고 굳이 플랙스 아이템에 퍼센트 너비를 지정해야 할 때가 있는데, 이 경우 그리드가 더 나은 선택이 될 수 있습니다.

### 박스 정렬

플랙스박스의 기능 중 많은 사람이 가장 흥미롭게 여겼던 것은 처음으로 적절한 정렬 제어 기능을 제공한다는 것입니다. 그래서 이젠 박스를 페이지의 중앙에 손쉽게 배치할 수도 있게 되었습니다. 플렉스 아이템은 플렉스 컨테이너의 높이만큼 늘어날 수도 있어서, 같은 높이의 칼럼 레이아웃을 구현할 수도 있습니다. 이것은 개발자가 아주 오랫동안 원했던 것이어서, 그동안 최소한 시각적 효과라도 흉내 내기 위해 온갖 종류의 꼼수를 고안해 내기도 했었습니다.

플랙스박스 표준 명세서에 있는 정렬 프로퍼티는 박스 정렬 레벨(Box Alignment Level) 3의 새로운 표준에 추가되었습니다. 이 말은 그리드 레이아웃을 비롯한 다른 표준에서도 사용할 수 있다는 뜻입니다. 그래서 미래에는 다른 레이아웃 방법에도 똑같이 적용될 수 있습니다.

이 가이드 시리즈의 후반부에서 박스 정렬에 관해 자세히 알아볼 것이며 또한, 그리드 레이아웃에서 어떻게 작동하는지도 살펴보겠습니다. 하지만 여기서는 플랙스박스와 그리드를 비교하는 간단한 예제를 살펴보겠습니다.

플랙스박스를 사용하는 첫 번째 예제에는 컨테이너 안에 세 개의 아이템이 있습니다. 감싸고 있는 요소에 `min-height`를 지정해서, 플랙스 컨테이너의 높이를 정의해 줍니다. 플렉스 컨테이너의 `align-items` (en-US) 값을 `flex-end`로 설정하여 아이템이 플랙스 컨테이너의 끝에 정렬되도록 했습니다. 또한, `box1`에 `align-self` (en-US) 프로퍼티를 설정하여 기본값을 덮어씌우면서 컨테이너의 높이 만큼 늘어나게 하였고, `box2`에는 플랙스 컨테이너의 시작 지점에 정렬되도록 하였습니다.
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
</div>
```

```css
.wrapper {
  display: flex;
  align-items: flex-end;
  min-height: 200px;
}
.box1 {
  align-self: stretch;
}
.box2 {
  align-self: flex-start;
}
```

### CSS 그리드에서의 정렬

다음 두 번째 예제에서는 그리드를 써서 앞에서와 똑같은 레이아웃을 구현했습니다. 이번에는 그리드 레이아웃에 적용할 때 쓰는 박스 정렬 프로퍼티를 사용하였습니다. 그래서 `flex-start`와 `flex-end`가 아닌 `start`와 `end`를 써서 정렬합니다. 그리드 레이아웃의 경우 해당 그리드 영역을 기준으로 내부에 있는 아이템들을 정렬합니다. 이번 경우에는 단일 그리드 셀로 되어 있지만, 그리드 영역이 여러 그리드 셀로 구성되어 있을 수도 있습니다.
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-items: end;
  grid-auto-rows: 200px;
}
.box1 {
  align-self: stretch;
}
.box2 {
  align-self: start;
}
```

### `fr` 단위와 `flex-basis`

우리는 이미 `fr` 단위가 어떻게 그리드 컨테이너 속 사용 가능한 공간을 비율에 따라 그리드 트랙에 할당하는지 보았습니다. `fr` 단위가 `minmax()` (en-US) 함수와 결합하면 플랙스박스의 `flex` 프로퍼티와 매우 유사한 동작을 구현할 수 있으며, 동시에 2차원 레이아웃을 구성할 수도 있습니다.

이전의 1차원과 2차원 레이아웃의 차이점을 보여주는 예제를 살펴보면, 두 레이아웃이 반응하는 방식에 차이가 있다는 점을 아실 수 있습니다. 플랙스 레이아웃의 경우, 브라우저 창을 더 넓거나 좁게 드래그하면, 플랙스 박스는 사용 가능한 공간에 따라 각 행에 나열되는 아이템의 수를 적절하게 조정합니다. 공간이 많다면 5개의 아이템 모두가 한 행에 들어갈 수 있을 것이며, 컨테이너 너비가 매우 좁다면 단지 하나의 아이템이 들어갈 만한 공간이 남을 수도 있을 겁니다.

반면에, 그리드 버전에는 항상 세 개의 열 트랙이 있게 됩니다. 트랙 자체가 넓어지거나 줄어들 수 있지만, 그리드를 정의할 때 세 개를 지정했으면 무조건 세 개의 트랙이 있게 됩니다.

#### 자동으로 채워지는 그리드 트랙

트랙의 목록을 생성할 때 반복 표기법과 `auto-fill` 및 `auto-fit` 프로퍼티를 사용하면 지정한 행과 열에 맞추면서도 플랙스박스와 유사한 효과를 내도록 콘텐츠를 정렬할 수도 있습니다.

다음 예제에서는 반복 표기법을 지정할 때 정수 대신 `auto-fill` 키워드를 사용하였고 기준 크기가 200픽셀이 되도록 트랙 목록을 설정했습니다. 즉, 그리드는 컨테이너에 200픽셀 너비의 세로 열 트랙을 채울 수 있을 만큼의 개수를 생성하게 됩니다.
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(auto-fill, 200px);
}
```

### 변동 가능한 트랙의 수

이것은 플랙스박스와 완전히 똑같지는 않습니다. 플랙스박스 예제에서는 아이템이 다음 줄로 행 바꿈 하기 전에는 기본값인 200픽셀보다 더 넓었습니다. 그리드에서는 `auto-fill`과 `minmax()` (en-US) 함수를 결합해서 비슷한 결과를 얻을 수 있습니다. 다음 예제에선 `minmax`를 써서 자동으로 채워지는 트랙을 만들었습니다. 트랙은 최소 200픽셀부터 시작해서 최대 `1fr`까지 늘어날 수 있도록 설정하였습니다. 브라우저는 우선 200픽셀 크기의 아이템을 (그리드 간격도 함께 고려해서) 컨테이너에 몇 개로 채울 수 있을지 계산을 하고 나서, 남아있는 공간을 최대치 `1fr` 기준으로 아이템들끼리 공유하면서 서로 늘어나도록 합니다.
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
```

이렇게 해서, 크기와 개수가 변동적인 트랙들로 구성된 그리드를 만들 수 있게 되었으며, 동시에 아이템들을 일정한 행과 열로 정렬할 수도 있음을 확인하였습니다.

그리드와 단독으로 위치를 지정한 요소
--------------------

그리드는 단독으로 위치 지정된 요소와 상호 작용하면서, 그리드 또는 그리드 영역 내에 아이템을 배치할 때 유용하게 사용될 수 있습니다. 표준 명세서에는 그리드 컨테이너가 요소를 감싸는 컨테이닝 블록(containing block)으로서, 그리드 컨테이너가 단독으로 위치를 지정한 아이템의 부모 요소일 때 동작하는 방식을 정의하고 있습니다.

### 컨테이닝 블록으로서의 그리드 컨테이너

그리드 컨테이너를 컨테이닝 블록으로 만들려면, 다른 단독으로 위치를 지정한 아이템을 감싸고 있는 요소를 컨테이닝 블록을 만들 때와 마찬가지로, 컨테이너에 position 프로퍼티로 relative 값을 추가해야 합니다. 이렇게 하면, 그리드 아이템에 `position: absolute`를 지정할 경우 그리드 컨테이너가 컨테이닝 블록이 되며, 또 해당 아이템에 그리드 위칫값이 추가로 지정되었을 때는, 배치된 그리드 영역이 컨테이닝 블록으로 작용합니다.

아래 예제에서는 네 개의 하위 아이템을 감싸는 wrapper 클래스의 블록이 있습니다. 3번 아이템은 단독으로 위치가 지정되었으며 라인을 기반으로 그리드에 배치되었습니다. 그리드 컨테이너에 `position: relative`를 지정해서 이 아이템이 위치를 잡을 때 참고하는 기준 요소가 됩니다.
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">
    This block is absolutely positioned. In this example the grid container is
    the containing block and so the absolute positioning offset values are
    calculated in from the outer edges of the area it has been placed into.
  </div>
  <div class="box4">Four</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 200px;
  grid-gap: 20px;
  position: relative;
}
.box3 {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 3;
  position: absolute;
  top: 40px;
  left: 40px;
}
```

여기서 아이템이 그리드의 세로 열 2번 라인부터 4번 라인까지, 그리고 가로 행 1번 라인을 시작으로 그리드 영역을 차지하고 있는 것을 확인하실 수 있습니다. 하지만, 단독으로 위치를 지정한 일반 아이템의 경우와 마찬가지로 문서 흐름에서 제외되면서, 자동 배치 규칙에 따라 해당 공간에 다른 아이템들을 배치하게 됩니다. 또한, 이로 인해 아이템이 추가 행을 생성하지 않게 되면서 가로 행 3번 라인까지 확장하지 않게 되었습니다.

만약에 `.box3`의 규칙 중에 `position: absolute`를 없애버리면, 위치를 지정하지 않았을 경우 표시될 원래의 자리로 돌아가는 것을 확인하실 수 있습니다.

### 부모 요소로서의 그리드 컨테이너

만약에 단독으로 위치를 지정한 자식 요소가 그리드 컨테이너에 속해 있지만, 해당 컨테이너가 위치를 참고하는 새로운 기준 요소로 정의되지 않았다면, 앞의 예제에서처럼 일반 배치 흐름에서 배제됩니다. 위치의 기준이 되는 요소는, 다른 레이아웃 방법에 공통으로 적용되는 것과 마찬가지로, 새로운 위치 기준 요소로 정의된 요소가 맡게 됩니다. 이번 경우에 만약 위에 있는 감싸는 요소에서 `position: relative`를 삭제한다면, 위치의 기준이 되는 것은 아래의 그림에서 보여주듯이 최상위 도큐먼트 오브젝트에 해당하는 기본 뷰포트(viewport)가 맡게 됩니다.

![부모 요소로서의 그리드 컨테이너 모습을 담은 그림](/ko/docs/Web/CSS/CSS_grid_layout/Relationship_of_grid_layout_with_other_layout_methods/2_abspos_example.png)

여기도 마찬가지로 해당 아이템은, 다른 아이템들의 크기 조정과 자동 배치와 관련해서, 더는 그리드 레이아웃에 관여하지 않게 됩니다.

### 부모 요소가 그리드 영역일 때

만약에 단독으로 위치를 지정한 아이템이 그리드 영역 안에 자리 잡고 있다면, 해당 영역을 위치의 기준이 되는 요소로 정의할 수 있습니다. 아래 예제에서는 전과 같은 그리드가 정의되어 있습니다만, 이번엔 그리드의 `.box3` 안에 또 하나의 아이템을 중첩해 놓았습니다.

`.box3`의 position 값으로 relative를 지정했으며 그 밑에 있는 아이템에는 원래의 위치에서 벗어난 값을 따로 지정하였습니다. 이 경우 위치의 기준이 되는 요소는 그리드 영역이 됩니다.
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
```

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">
    Three
    <div class="abspos">
      This block is absolutely positioned. In this example the grid area is the
      containing block and so the absolute positioning offset values are
      calculated in from the outer edges of the grid area.
    </div>
  </div>
  <div class="box4">Four</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 200px;
  grid-gap: 20px;
}
.box3 {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 3;
  position: relative;
}
.abspos {
  position: absolute;
  top: 40px;
  left: 40px;
  background-color: rgba(255, 255, 255, 0.5);
  border: 1px solid rgba(0, 0, 0, 0.5);
  color: #000;
  padding: 10px;
}
```

그리드와 `display: contents`
------------------------

마지막으로 눈여겨볼 또 하나의 레이아웃 표준과 관련된 상호 작용으로 CSS 그리드 레이아웃과 `display: contents` 사이의 상호 작용이 있습니다. display 프로퍼티의`contents` 값은 Display 표준 명세서에 새로 정의된 것으로 다음과 같이 설명되어 있습니다:

>
> "요소 자신은 어떠한 박스도 생성하지 않지만, 대신 포함하고 있는 하위 자식 요소와 가상 요소(pseudo-elements)가 평소처럼 박스를 생성하게 됩니다. 그래서 박스 생성과 레이아웃을 구현할 때, 문서의 계층 구조상 해당 요소가 아래 자식 요소와 가상 요소로 대체된 것처럼 다루어집니다."
>
>
>

만약에 아이템에 `display:` `contents`를 지정하면 보통 해당 요소가 만드는 박스는 사라지고, 자식 요소의 박스가 한 단계 상승한 것처럼 그 자리를 차지하게 됩니다. 이 얘기는 그리드 아이템의 자식 요소가 그리드 아이템이 될 수도 있다는 뜻입니다. 이상하게 들리시죠? 다음에 간단한 예를 들어보겠습니다. 아래 마크업에는 그리드가 있고, 이 그리드에 있는 첫 번째 아이템이 세 개의 열 트랙 모두를 가로지르도록 설정하였습니다. 또한, 이 아이템은 세 개의 중첩된 아이템들을 포함하고 있습니다. 이 아이템들은 컨테이너 바로 밑에 있는 자식 요소가 아니므로, 그리드 레이아웃의 일원으로 참여하지 않으면서 보통의 일반 블록 레이아웃으로 표시됩니다.

### Grid layout with nested child elements
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.box {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
.nested {
  border: 2px solid #ffec99;
  border-radius: 5px;
  background-color: #fff9db;
  padding: 1em;
}
```

```html
<div class="wrapper">
  <div class="box box1">
    <div class="nested">a</div>
    <div class="nested">b</div>
    <div class="nested">c</div>
  </div>
  <div class="box box2">Two</div>
  <div class="box box3">Three</div>
  <div class="box box4">Four</div>
  <div class="box box5">Five</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: minmax(100px, auto);
}
.box1 {
  grid-column-start: 1;
  grid-column-end: 4;
}
```

### Using `display: contents`

이제 `.box1`에 `display:` `contents`규칙을 추가하면, 해당 아이템이 차지하고 있는 박스가 사라지면서 하위 아이템들이 그리드 아이템 자격을 얻게 되어 자동 배치 규칙에 따라 알아서 배치됩니다.
```

\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.box {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
.nested {
  border: 2px solid #ffec99;
  border-radius: 5px;
  background-color: #fff9db;
  padding: 1em;
}
```

```html
<div class="wrapper">
  <div class="box box1">
    <div class="nested">a</div>
    <div class="nested">b</div>
    <div class="nested">c</div>
  </div>
  <div class="box box2">Two</div>
  <div class="box box3">Three</div>
  <div class="box box4">Four</div>
  <div class="box box5">Five</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: minmax(100px, auto);
}
.box1 {
  grid-column-start: 1;
  grid-column-end: 4;
  display: contents;
}
```

이것은 중첩된 아이템을 그리드의 일부분인 것처럼 작용하게 하는 방법으로 사용될 수 있으며, 또한 서브 그리드가 구현된다면 해결될 수 있는 문제를 피해 가는 방법이 될 수도 있습니다. 물론, 플랙스박스에서도 비슷하게 `display:` `contents`를 이용해서 중첩된 아이템이 플랙스 아이템처럼 작용하도록 만들 수도 있습니다.

이번 가이드에서 보셨듯이 CSS 그리드 레이아웃은 단지 여러분이 구현해 볼 수 있는 여러 기술 중 한 부분일 뿐입니다. 원하시는 다양한 효과를 얻기 위해서 다른 레이아웃 기술끼리 서로 혼합해서 사용하는 것을 두려워하지 마십시오.

1. **CSS**
2. **CSS Reference**
3. CSS 그리드 레이아웃
4. **가이드**
    1. 그리드 레이아웃의 기본 개념
    2. 다른 레이아웃 방법과의 관계
    3. 라인을 기준으로 한 아이템 배치
    4. 그리드 템플릿 영역
    5. 이름이 주어진 그리드 라인을 이용한 레이아웃
    6. Auto-placement in grid layout (en-US)
    7. Box alignment in grid layout (en-US)
    8. Grids, logical values, and writing modes (en-US)
    9. CSS Grid Layout and Accessibility (en-US)
    10. CSS Grid Layout and Progressive Enhancement (en-US)
    11. Realizing common layouts using grids (en-US)
5. **프로퍼티**
    1. grid (en-US)
    2. grid-area (en-US)
    3. grid-auto-columns (en-US)
    4. grid-auto-flow (en-US)
    5. grid-auto-rows (en-US)
    6. grid-column (en-US)
    7. grid-column-end (en-US)
    8. grid-column-gap (en-US)
    9. grid-column-start (en-US)
    10. grid-gap (en-US)
    11. grid-row (en-US)
    12. grid-row-end (en-US)
    13. grid-row-gap (en-US)
    14. grid-row-start (en-US)
    15. grid-template (en-US)
    16. grid-template-areas (en-US)
    17. grid-template-columns
    18. grid-template-rows (en-US)
6. **용어집**
    1. Grid
    2. Grid lines
    3. Grid tracks
    4. Grid cell
    5. Grid areas
    6. Gutters
    7. Grid Axis
    8. Grid row (en-US)
    9. Grid column


Basic concepts of grid layout - CSS: Cascading Style Sheets

Basic concepts of grid layout
=============================

CSS 그리드 레이아웃(Grid Layout)은 CSS에 2차원의 그리드 시스템을 도입했습니다. 그리드는 주요 페이지 영역을 설계하거나 작은 사용자 인터페이스 요소를 배치하는 데 사용할 수 있습니다. 이 문서에서는 CSS 그리드 레이아웃 및 CSS 그리드 레이아웃 레벨 1 명세서에 포함된 새로운 기술 용어를 소개합니다. 이번 개요에 소개된 기능은 나머지 안내 문서에서 자세히 설명합니다.

그리드가 무엇인가요?
-----------

그리드는 수평선과 수직선이 교차해서 이루어진 집합체입니다 - 하나의 집합체는 세로 열을 그리고 다른 하나는 가로 행을 정의합니다. 각 요소는 이러한 열과 행으로 된 라인을 따라 생성된 그리드에 배치할 수 있습니다. CSS 그리드 레이아웃에는 다음과 같은 기능이 있습니다:

### 고정되거나 혹은 유연한 트랙 크기

예를 들면, 픽셀 단위를 써서 트랙 크기가 고정된 그리드를 만들 수 있습니다. 이렇게 하면, 원하시는 레이아웃에 꼭 맞도록 픽셀 크기를 지정해서 그리드를 설정하실 수 있습니다. 또한, 퍼센트 혹은 이런 목적에 적합하도록 설계된 새로운 `fr` 단위의 가변 크기를 지정해서, 좀 더 유연한 성질의 그리드를 만들 수도 있습니다.

### 아이템 배치

아이템은 라인 번호, 이름 또는 그리드 영역을 지정해서 그리드의 정확한 위치에 배치할 수 있습니다. 그리드는 또 명확하게 위치가 지정되지 않은 아이템을 알아서 적절히 배치하는 알고리즘도 가지고 있습니다.

### 콘텐츠를 담기 위한 추가 트랙의 생성

그리드 레이아웃으로 그리드를 명시적으로 정의할 수 있지만, 지정된 그리드 밖에 따로 추가되는 콘텐츠에 대응하여 필요에 따라 행과 열을 추가할 수 있도록 표준 문서에서 기술하고 있습니다. 일 예로 "컨테이너에 들어갈 수 있는 만큼의 세로 열"을 추가하는 기능이 포함되었습니다.

### 정렬 제어

그리드에는 정렬 기능이 있어서 그리드 영역에 아이템을 배치한 후 어떻게 정렬할지, 그리고 전체 그리드가 정렬되는 방식을 제어할 수 있습니다.

### 겹치는 콘텐츠 제어

그리드 셀에 하나 이상의 아이템을 배치하거나 그리드 영역을 부분적으로 서로 겹치게 할 수 있습니다. 이렇게 생긴 중첩의 우선순위는 나중에 `z-index` 프로퍼티로 제어할 수 있습니다.

그리드는 아주 강력한 기능을 담은 표준이라서 플랙스박스(flexbox)와 같은 CSS의 다른 부분과 결합하면, 이전에는 CSS에서 불가능했던 레이아웃을 만들 수 있도록 도와줍니다. 이 모든 것은 **그리드 컨테이너**에서 그리드를 생성하는 것부터 시작합니다.

그리드 컨테이너
--------

*그리드 컨테이너*는 요소에 `display: grid` 또는 `display: inline-grid`를 선언하여 만듭니다. 이렇게 하면 해당 요소 *바로 밑에 있는 모든 자식 요소*는 *그리드 아이템*이 됩니다.

다음 예제에는 클래스로 wrapper라는 이름을 가진 div이 있고, 안에는 다섯 개의 자식 요소가 있습니다.

```html
<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
</div>
```

이제 `.wrapper` 요소를 그리드 컨테이너로 지정합니다.

```css
.wrapper {
  display: grid;
}
```

```
\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}

.nested {
  border: 2px solid #ffec99;
  border-radius: 5px;
  background-color: #fff9db;
  padding: 1em;
}
```

바로 밑에 있는 모든 자식 요소는 이제 그리드 아이템이 됩니다. 이렇게 하면 웹 브라우저에서 보이는 모습이 그리드로 전환하기 전과 별 차이가 없는데, 이는 그리드가 우선 아이템을 단일 열 형태의 구조를 가진 그리드를 생성하였기 때문입니다. 이 시점에서 Firefox Developer Edition에서 작업하는 것이 유용하실 텐데, 여기엔 개발자 도구의 일부로 Grid Inspector (en-US) 기능을 제공합니다. Firefox에서 이 예제의 그리드를 검사해보면, `grid` 값 바로 옆에 작은 아이콘이 보이실 겁니다. 이 아이콘을 클릭하면 해당 요소의 그리드가 브라우저 창 위에 중첩되어 표시됩니다.

![그리드를 살펴보기 위해 개발자 도구에 있는 그리드 하이라이터를 사용하는 모습](/ko/docs/Web/CSS/CSS_grid_layout/Basic_concepts_of_grid_layout/1-grid-inspector.png)

CSS 그리드 레이아웃을 배우면서 작업하실 때 이 도구를 사용하면 그리드에서 발생하는 상황을 시각적으로 더 잘 파악하실 수 있습니다.

이제 이것을 전형적인 그리드 형태의 모양으로 만들어 주려면 세로 방향의 트랙을 더 추가하면 됩니다.

그리드 트랙
------

그리드의 행과 열은 `grid-template-columns` 및 `grid-template-rows` (en-US) 프로퍼티로 정의합니다. 이렇게 하면, 그리드 트랙도 함께 정의됩니다. *그리드 트랙*은 그리드에 그려진 두 라인 사이의 공간을 나타냅니다. 아래 그림에서는 그리드의 첫 번째 가로 행에 놓여있는 트랙이 돋보이게 표시된 것을 확인하실 수 있습니다.

![](/ko/docs/Web/CSS/CSS_grid_layout/Basic_concepts_of_grid_layout/1_grid_track.png)

앞의 예제에서 `grid-template-columns` 프로퍼티를 추가하고 세로 열에 놓이게 될 트랙의 크기를 정의해 줍니다.

이제 200픽셀의 너비를 가진 세로 열 방향의 트랙 세 개를 생성합니다. 자식 아이템들은 이제 그리드에 있는 각자의 그리드 셀 위에 배치됩니다.

```html
<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: 200px 200px 200px;
}
```

```
\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}

.nested {
  border: 2px solid #ffec99;
  border-radius: 5px;
  background-color: #fff9db;
  padding: 1em;
}
```

### fr 단위

트랙은 모든 종류의 길이 단위를 써서 정의할 수 있습니다. 또한, 그리드에는 유연한 크기의 그리드 트랙을 생성하는 데 사용할 수 있는 단위를 추가로 소개하고 있습니다. 새로 소개된 `fr` 단위는 그리드 컨테이너에 남아 있는 사용 가능한 공간의 일정 비율을 나타냅니다. 다음에 정의된 그리드에서는 남아 있는 공간에 따라 확장 및 축소되는 같은 너비의 트랙 3개를 생성합니다.

```html
<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}
```

```
\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}

.nested {
  border: 2px solid #ffec99;
  border-radius: 5px;
  background-color: #fff9db;
  padding: 1em;
}
```

다음 예제에서는 `2fr` 크기의 트랙 하나와 `1fr` 트랙 두 개를 지정하였습니다. 사용 가능한 공간은 4개로 나뉘면서, 공간 두 개는 첫 번째 트랙에 제공하고 나머지 공간 한 부분씩을 다음 두 트랙에 각각 제공합니다.

```css
.wrapper {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
}
```

이번 마지막 예에서는 고정된 크기의 트랙과 비율 단위로 지정한 트랙이 섞여 있습니다. 첫 번째 트랙은 500픽셀의 공간을 차지하므로 이 고정 너비는 사용 가능한 공간에서 제외됩니다. 나머지 공간은 3개의 부분으로 나뉘며 2개의 유연한 트랙에 비율에 맞게 할당됩니다.

```css
.wrapper {
  display: grid;
  grid-template-columns: 500px 1fr 2fr;
}
```

### `repeat()` 표기법으로 트랙 나열

많은 트랙을 포함하는 커다란 그리드는 `repeat()` 표기법을 사용하여 트랙의 전체 또는 일부분을 반복해서 나열해 줄 수 있습니다. 예를 들어 다음과 같이 정의된 그리드의 경우:

```css
.wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}
```

다음과 같이 작성할 수도 있습니다:

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
```

반복 표기법은 트랙의 목록 중 일부분에만 사용할 수도 있습니다. 아래 예제에서는 처음엔 20픽셀 크기의 트랙을 생성하고 다음에 `1fr` 크기의 트랙을 6번 반복해서 채운 후 마지막에 20픽셀 트랙을 붙여서 그리드를 완성합니다.

```css
.wrapper {
  display: grid;
  grid-template-columns: 20px repeat(6, 1fr) 20px;
}
```

반복 표기법은 트랙의 목록도 함께 나열해서 지정할 수 있는데, 이렇게 하면 트랙의 반복 패턴을 생성해서 사용하게 됩니다. 다음 예제는 그리드가 10개의 트랙으로 구성되어 있으며, `1fr` 크기의 트랙 다음에 `2fr` 크기 트랙이 위치하고, 이 형태가 5회 반복됩니다.

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(5, 1fr 2fr);
}
```

### 잠재적 그리고 명시적 그리드

지금까지는 그리드 예제를 만들 때마다 `grid-template-columns` 프로퍼티를 써서 세로 열의 트랙을 정의해 주었습니다만, 가로 행은 그리드가 콘텐츠에 맞게 알아서 새로운 행을 만들도록 했습니다. 이렇게 만들어진 행은 잠재적 그리드 안에서 생성됩니다. 명시적 그리드는 `grid-template-columns` 및 `grid-template-rows` (en-US)로 직접 정의한 행과 열로 이루어진 그리드를 말합니다. 만약에 이렇게 정의된 그리드 밖에 무언가를 배치할 땐, 늘어난 콘텐츠 양 때문에 더 많은 그리드 트랙이 필요하고, 그리드는 잠재적 그리드에 새로운 행과 열을 만들게 됩니다. 이렇게 해서 생긴 트랙은 기본적으로 크기가 자동으로 정해지는데, 트랙 내부의 내용물에 따라 크기가 조정됩니다.

물론 잠재적 그리드에서 생성된 트랙의 크기는 `grid-auto-rows` (en-US) 및 `grid-auto-columns` (en-US) 프로퍼티를 써서 지정해줄 수도 있습니다.

아래 예제에서는 잠재적 그리드에서 생성된 트랙의 높이가 반드시 200픽셀이 되도록 `grid-auto-rows`를 사용하여 하였습니다.

```html
<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 200px;
}
```

```
\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}

.nested {
  border: 2px solid #ffec99;
  border-radius: 5px;
  background-color: #fff9db;
  padding: 1em;
}
```

### 트랙 크기 조정과 `minmax()`

명시적 그리드를 설정하거나 자동으로 생성된 행이나 열의 크기를 정의할 때, 트랙의 최소 크기를 정해도 나중에 추가되는 콘텐츠에 맞게 늘어나도록 하고 싶을 때가 있을 겁니다. 예를 들면, 가로 행의 높이가 100픽셀 밑으로 줄어드는 것은 막고 싶지만, 콘텐츠가 300픽셀 높이까지 늘어나면 그에 따라 행의 높이도 같이 늘어나길 원할 때가 있습니다.

이런 경우를 고려해서 그리드는 `minmax()` (en-US) 함수를 제공하고 있습니다. 다음 예제에서는 `grid-auto-rows` (en-US) 값에 `minmax()` 를 사용하였습니다. 자동으로 생성된 행의 높이는 최소 100픽셀이고 최댓값은 `auto`입니다. `auto`를 지정하면 크기는 콘텐츠의 크기를 살피게 되는데, 가로 행에 있는 가장 높은 셀의 크기만큼 자동으로 늘어나서 부족한 공간을 메꿔줍니다.

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: minmax(100px, auto);
}
```

```
\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}

.nested {
  border: 2px solid #ffec99;
  border-radius: 5px;
  background-color: #fff9db;
  padding: 1em;
}
```

```html
<div class="wrapper">
  <div>One</div>
  <div>
    Two
    <p>I have some more content in.</p>
    <p>This makes me taller than 100 pixels.</p>
  </div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
</div>
```

그리드 라인
------

그리드를 정의할 때 라인이 아닌 그리드 트랙을 정의한다는 점을 명심해야 합니다. 그러면 그리드는 아이템을 배치할 때 쓸 수 있게 번호가 매겨진 라인을 자동으로 제공합니다. 아래 그림처럼, 그리드가 세 개의 세로 열(Column)과 두 개의 가로 행(Row)으로 이루어져 있다면, 네 개의 Grid Line이 Column으로 자리 잡게 됩니다.

![번호가 매겨진 그리드 라인을 보여주는 다이어그램.](/ko/docs/Web/CSS/CSS_grid_layout/Basic_concepts_of_grid_layout/1_diagram_numbered_grid_lines.png)

라인은 문서의 작성 모드에 따라 번호가 매겨집니다. 왼쪽에서 오른쪽으로 쓰는 언어에서는 라인 1이 그리드의 왼쪽에 있습니다. 반대로 오른쪽에서 왼쪽으로 쓰는 언어에서는 그리드의 오른쪽에 있게 됩니다. 또한, 라인에 이름도 지정할 수 있으며, 자세한 방법은 이 시리즈의 후반부에서 살펴보겠습니다.

### 라인을 이용한 아이템 배치

라인에 기반을 둔 배치 방법에 대해서는 다음에 더 자세히 탐구해 볼 예정입니다. 이번 예제에서는 아주 간단한 방법을 알아보겠습니다. 아이템을 배치할 때 트랙이 아닌 라인의 관점에서 정의해 보겠습니다.

아래 예제에선 처음 두 개의 아이템을 세 개의 열 방향 트랙으로 구성된 그리드 위에 `grid-column-start` (en-US), `grid-column-end` (en-US), `grid-row-start` (en-US) 그리고 `grid-row-end` (en-US) 프로퍼티를 써서 배치합니다. 왼쪽에서 오른쪽으로 작업하면서, 첫 번째 아이템은 세로 열 방향의 1번 라인에 배치되고 세로 열 방향 4번 라인까지 확장됩니다. 이 경우에는 그리드의 맨 오른쪽 라인까지 해당합니다. 그리고 가로 방향의 라인을 기준으로 1번 라인부터 시작해서 행 3번 라인까지 차지하면서 결국, 두 개의 가로 행 트랙을 가로질러 걸치게 됩니다.

두 번째 아이템은 그리드 세로 열의 1번 라인에서 시작해서 트랙 하나에 걸쳐 있습니다. 여기엔 기본값을 사용해서 마지막 라인은 지정할 필요가 없습니다. 가로 행 방향 라인을 기준으로 3번의 라인부터 5번 라인까지 두 개의 가로 행 트랙에 걸쳐 있습니다. 나머지 아이템은 그리드 빈 자라에 자동으로 배치됩니다.

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
  <div class="box4">Four</div>
  <div class="box5">Five</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 100px;
}

.box1 {
  grid-column-start: 1;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 3;
}

.box2 {
  grid-column-start: 1;
  grid-row-start: 3;
  grid-row-end: 5;
}
```

```
\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}

.nested {
  border: 2px solid #ffec99;
  border-radius: 5px;
  background-color: #fff9db;
  padding: 1em;
}
```

Firefox 개발자 도구에 있는 Grid Inspector (en-US)를 사용하면 아이템이 그리드 라인에 어떻게 배치되어 있는지 이해하기 훨씬 쉽다는 점도 잊지 마십시오.

그리드 셀
-----

*그리드 셀*은 그리드에 있는 가장 작은 구성원입니다. 개념상 테이블에 있는 셀과 비슷합니다. 앞의 예제에서 보셨듯이, 부모 요소에 그리드를 정의하면 자식 아이템은 지정된 그리드 셀에 각자 하나씩 나열되어 배치됩니다. 아래 그림에서는 그리드의 첫 번째 셀을 강조 표시했습니다.

![강조 표시된 그리드의 첫 번째 셀](/ko/docs/Web/CSS/CSS_grid_layout/Basic_concepts_of_grid_layout/1_grid_cell.png)

그리드 영역
------

아이템은 행 또는 열 방향 어느 쪽으로든 하나 이상의 셀에 걸쳐있을 수 있으며 이렇게 해서 *그리드 영역*을 만듭니다. 그리드 영역은 직사각형이어야 하며, 예를 들어 L 자 형태의 영역을 생성할 수 없습니다. 아래 강조 표시된 그리드 영역은 2개의 행과 2개의 열 트랙에 걸쳐 있습니다.

![그리드 영역의 예](/ko/docs/Web/CSS/CSS_grid_layout/Basic_concepts_of_grid_layout/1_grid_area.png)

경계 여백
-----

그리드 셀 사이의 *경계 여백* 혹은 *간격은* `grid-column-gap` (en-US) 및 `grid-row-gap` (en-US) 프로퍼티를 지정해서 생성할 수 있으며, 짧게 `grid-gap` (en-US)으로 지정할 수도 있습니다. 아래의 예제에서는 세로 열 사이의 간격은 10픽셀이고 가로 행 사이의 간격은 `1em`입니다.

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-column-gap: 10px;
  grid-row-gap: 1em;
}
```

```html
<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
</div>
```

```
\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}

.nested {
  border: 2px solid #ffec99;
  border-radius: 5px;
  background-color: #fff9db;
  padding: 1em;
}
```

간격이 차지하는 공간은 길이가 유연한 `fr` 단위로 지정한 트랙에 할당하기 전에 우선 고려되어 배분됩니다. 그래서 일반 그리드 트랙처럼 간격은 크기 조정의 목적으로 활용될 수 있으나, 이 공간에는 아무것도 배치할 수 없습니다. 라인 기반 위치 지정 측면에선 간격은 그저 굵은 선처럼 작용합니다.

중첩 그리드
------

그리드 아이템은 자기 자신이 그리드 컨테이너가 될 수도 있습니다. 다음 예제는 이전에 생성했던 3개의 세로 열로 구성된 그리드가 있으며, 여기에 따로 위치가 지정된 두 개의 아이템을 배치해 놓은 모습입니다. 이번 경우엔 첫 번째 아이템이 몇 개의 하위 아이템을 포함하고 있습니다. 이 아이템들은 그리드 바로 밑에 있는 요소가 아니므로 그리드 레이아웃에 관여하지 않고 정상적인 문서 흐름에 따라 표시됩니다.

```html
<div class="wrapper">
  <div class="box box1">
    <div class="nested">a</div>
    <div class="nested">b</div>
    <div class="nested">c</div>
  </div>
  <div class="box box2">Two</div>
  <div class="box box3">Three</div>
  <div class="box box4">Four</div>
  <div class="box box5">Five</div>
</div>
```

![문서 흐름에 따라 표시된 중첩 그리드](/ko/docs/Web/CSS/CSS_grid_layout/Basic_concepts_of_grid_layout/1_nested_grids_in_flow.png)

만약에 `box1에` `display: grid를` 설정하면, 여기에 트랙을 정의할 수 있게 되면서 또 하나의 그리드를 생성하게 됩니다. 이렇게 해서 그 밑의 아이템들은 새 그리드 정의에 따라 배치됩니다.

```css
.box1 {
  grid-column-start: 1;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 3;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
```

```
\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.box {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}

.nested {
  border: 2px solid #ffec99;
  border-radius: 5px;
  background-color: #fff9db;
  padding: 1em;
}
```

이 경우 중첩된 그리드는 상위 부모 요소의 그리드와 아무런 관계가 없습니다. 예제에서 볼 수 있듯이 부모 요소의 `grid-gap` (en-US)을 그대로 물려받지 않았고, 중첩된 그리드의 라인은 부모 요소의 그리드 라인과도 일렬로 정렬되지 않은 것을 확인하실 수 있습니다.

### 서브 그리드

레벨 1 그리드 표준에는 \*서브 그리드(subgrid)\*라는 기능이 있어서 부모 요소에 있는 그리드 트랙의 정의를 중첩된 그리드에도 적용해서 생성할 수 있도록 하였습니다.

**참고:** 서브 그리드는 아직 모든 브라우저에서 구현되지 않았고 나중에 표준이 변경될 수도 있습니다.

최근 작성된 표준에 따르면, 위 중첩 그리드 예시에 썼던 `display: grid` 대신 `display: subgrid`를 써주고 트랙의 정의는 제거합니다. 이렇게 하면 중첩된 그리드는 부모 요소의 그리드 트랙을 그대로 참고해서 아이템을 배치하게 됩니다.

중첩된 그리드는 행과 열 모두에 걸쳐 있음을 유의해야 합니다. 서브 그리드를 작업할 때는 잠재적 그리드의 개념을 적용할 수 없습니다. 즉, 부모 요소의 그리드에 모든 하위 아이템들을 담을 만큼의 충분한 행과 열의 트랙이 있는지 꼭 확인해야 합니다.

```css
.box1 {
  grid-column-start: 1;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 3;
  display: subgrid;
}
```

`z-index`를 이용한 아이템 중첩도 조정
-------------------------

그리드 아이템은 서로 같은 셀을 차지할 수 있습니다. 앞서 라인 번호로 아이템의 위치를 지정했던 예제로 돌아가서, 여기에 다음과 같이 두 아이템이 서로 자리가 겹치도록 수정합니다.

```html
<div class="wrapper">
  <div class="box box1">One</div>
  <div class="box box2">Two</div>
  <div class="box box3">Three</div>
  <div class="box box4">Four</div>
  <div class="box box5">Five</div>
</div>
```

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 100px;
}

.box1 {
  grid-column-start: 1;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 3;
}

.box2 {
  grid-column-start: 1;
  grid-row-start: 2;
  grid-row-end: 4;
}
```

```
\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.box {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}

.nested {
  border: 2px solid #ffec99;
  border-radius: 5px;
  background-color: #fff9db;
  padding: 1em;
}
```

`box2` 아이템은 이제 `box1`과 겹치게 되고, 소스 순서에서 나중에 위치하므로 맨 위에 표시됩니다.

### 중첩의 순서 조정

위치를 따로 지정한 아이템과 마찬가지로, 아이템이 위아래로 중첩되는 순서는 `z-index` 프로퍼티를 써서 제어할 수 있습니다. 만약에 `box2`에 `box1` 보다 더 낮은 `z-index`를 지정하면 `box1` 아래로 중첩되어 표시됩니다.

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 100px;
}

.box1 {
  grid-column-start: 1;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 3;
  z-index: 2;
}

.box2 {
  grid-column-start: 1;
  grid-row-start: 2;
  grid-row-end: 4;
  z-index: 1;
}
```

```
<div class="wrapper">
  <div class="box box1">One</div>
  <div class="box box2">Two</div>
  <div class="box box3">Three</div>
  <div class="box box4">Four</div>
  <div class="box box5">Five</div>
</div>
```

```
\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.box {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}

.nested {
  border: 2px solid #ffec99;
  border-radius: 5px;
  background-color: #fff9db;
  padding: 1em;
}
```

다음 단계
-----

이 글에서는 Grid 레이아웃 표준 문서에 나와 있는 내용을 아주 간단히 살펴보았습니다. 코드 예제를 좀 더 연구해 보시고, 안내서의 다음 부분으로 넘어가서 CSS 그리드 레이아웃의 세부 사항을 조금 더 심도 있게 살펴보시기 바랍니다.

1. **CSS**
2. **CSS Reference**
3. CSS 그리드 레이아웃
4. **가이드**
    1. 그리드 레이아웃의 기본 개념
    2. 다른 레이아웃 방법과의 관계
    3. 라인을 기준으로 한 아이템 배치
    4. 그리드 템플릿 영역
    5. 이름이 주어진 그리드 라인을 이용한 레이아웃
    6. Auto-placement in grid layout (en-US)
    7. Box alignment in grid layout (en-US)
    8. Grids, logical values and writing modes (en-US)
    9. CSS Grid Layout and Accessibility (en-US)
    10. CSS Grid Layout and Progressive Enhancement (en-US)
    11. Realizing common layouts using grids (en-US)
5. **프로퍼티**
    1. grid (en-US)
    2. grid-area (en-US)
    3. grid-auto-columns (en-US)
    4. grid-auto-flow (en-US)
    5. grid-auto-rows (en-US)
    6. grid-column (en-US)
    7. grid-column-end (en-US)
    8. grid-column-gap (en-US)
    9. grid-column-start (en-US)
    10. grid-gap (en-US)
    11. grid-row (en-US)
    12. grid-row-end (en-US)
    13. grid-row-gap (en-US)
    14. grid-row-start (en-US)
    15. grid-template (en-US)
    16. grid-template-areas (en-US)
    17. grid-template-columns
    18. grid-template-rows (en-US)
6. **용어집**
    1. Grid
    2. Grid lines
    3. Grid tracks
    4. Grid cell
    5. Grid areas
    6. Gutters
    7. Grid Axis
    8. Grid row (en-US)
    9. Grid column


flexbox의 기본 개념 - CSS: Cascading Style Sheets

flexbox의 기본 개념
==============

일명 flexbox라 불리는 Flexible Box module은 flexbox 인터페이스 내의 아이템 간 공간 배분과 강력한 정렬 기능을 제공하기 위한 1차원 레이아웃 모델 로 설계되었습니다. 이 글에서는 flexbox의 주요 기능에 대한 개요를 다룹니다. 더 자세한 내용은 가이드의 다른 글에서 탐구하게 될 것입니다.

flexbox를 1차원이라 칭하는 것은, 레이아웃을 다룰 때 한 번에 하나의 차원(행이나 열)만을 다룬다는 뜻입니다. 이는 행과 열을 함께 조절하는 CSS 그리드 레이아웃의 2차원 모델과는 대조됩니다.

flexbox의 두 개의 축
---------------

flexbox를 다루려면 주축과 교차축이라는 두 개의 축에 대한 정의를 알아야 합니다. 주축은 `flex-direction` 속성을 사용하여 지정하며 교차축은 이에 수직인 축으로 결정됩니다. flexbox의 동작은 결국 이 두 개의 축에 대한 문제로 환원되기 때문에 이들이 어떻게 동작하는지 처음부터 이해하는 것이 중요합니다.

### 주축

주축은 `flex-direction`에 의해 정의되며 4개의 값을 가질 수 있습니다:

* `row`
* `row-reverse`
* `column`
* `column-reverse`

`row` 혹은 `row-reverse`를 선택하면 주축은 **인라인 방향**으로 행을 따릅니다.

![If flex-direction is set to row the main axis runs along the row in the inline direction.](/ko/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox/basics1.png)

`column` 혹은 `column-reverse` 을 선택하면 주축은 페이지 상단에서 하단으로 **블록 방향**을 따릅니다.

![If flex-direction is set to column the main axis runs in the block direction.](/ko/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox/basics2.png)

### 교차축

교차축은 주축에 수직하므로, 만약 `flex-direction`(주축)이 `row` 나 `row-reverse` 라면 교차축은 열 방향을 따릅니다.

![If flex-direction is set to row then the cross axis runs in the block direction.](/ko/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox/basics3.png)

주축이 `column` 혹은 `column-reverse` 라면 교차축은 행 방향을 따릅니다.

![If flex-direction is set to column then the cross axis runs in the inline direction.](/ko/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox/basics4.png)

flex 요소를 정렬하고 끝을 맞추(justify)려면 어느 축이 어느 방향인지 이해하는 것이 중요합니다; flexbox는 주축, 교차축을 따라 항목을 정렬하고 끝을 맞추는 각종 속성들을 적용하는 방식으로 동작합니다.

시작선과 끝선
-------

flexbox가 쓰기 방법(writing mode)을 가정하지 않는다는 것은 상당히 중요합니다. 과거의 CSS는 왼쪽에서 오른쪽으로 향하는 가로 방향의 쓰기 방법에 치우쳐 있었습니다. 하지만 현대의 레이아웃은 다양한 쓰기 방법을 포괄해야 하므로, 더이상 텍스트가 문서의 왼쪽 상단에서 시작해서 오른쪽으로 향한다고 가정하지 않습니다. 새 라인이 항상 아래에 쌓인다고 가정하지도 않습니다.

다른 글에서 flexbox와 쓰기 방법 명세(writing mode spec.)가 어떤 관련이 있는지 알아볼 수 있습니다. 그 전에, 이 글에서 flex 요소의 정렬 방향에 "왼쪽, 오른쪽, 위, 아래"를 사용하지 않는 이유를 알 수 있었으면 합니다.

`flex-direction`이 `row`고 영어 문장을 문서에 쓰고 있다면, 주축의 시작선은 왼쪽 끝, 끝선은 오른쪽 끝이 될 것입니다.

![Working in English the start edge is on the left.](/ko/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox/basics5.png)

아랍어 문장을 쓰고 있다면, 주축의 시작선은 오른쪽 끝, 끝 선은 왼쪽 끝이 될 것입니다.

![The start edge in a RTL language is on the right.](/ko/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox/basics6.png)

영어와 아랍어는 모두 가로 쓰기를 채택하고 있으므로 두 예시에서 교차축의 시작선은 **flex 컨테이너**의 위 끝이며 끝선은 아래 끝입니다.

조금만 지나면 왼쪽-오른쪽으로 생각하는 것보다 시작선-끝선으로 생각하는 것이 금새 자연스러워질 것입니다. 동일한 패턴을 따르는 CSS 그리드 레이아웃 같은 방법을 다룰 때도 쉽게 적응할 수 있을 것입니다.

flex 컨테이너
---------

문서의 영역 중에서 flexbox가 놓여있는 영역을 **flex 컨테이너**라고 부릅니다. flex 컨테이너를 생성하려면 영역 내의 컨테이너 요소의 `display` (en-US) 값을 `flex` 혹은 `inline-flex`로 지정합니다. 이 값이 지정된 컨테이너의 일차 자식(direct children) 요소가 **flex 항목**이 됩니다. display 속성만 지정하여 flex 컨테이너를 생성하면 다른 flex 관련 속성들은 아래처럼 기본 값이 지정됩니다.

* 항목은 행으로 나열됩니다. (`flex-direction` 속성의 기본값은 `row`입니다).
* 항목은 주축의 시작 선에서 시작합니다.
* 항목은 주 차원 위에서 늘어나지는 않지만 줄어들 수 있습니다.
* 항목은 교차축의 크기를 채우기 위해 늘어납니다.
* `flex-basis` 속성은 `auto`로 지정됩니다.
* `flex-wrap` 속성은 `nowrap`으로 지정됩니다.

이렇게되면 **flex 항목**들은 각 항목 별 내부 요소의 크기로 주축을 따라 정렬됩니다. 컨테이너의 크기보다 더 많은 항목이 있을 경우 행을 바꾸지 않고 주축 방향으로 흘러 넘치게 됩니다. 어떤 항목이 다른 항목보다 높이 값이 크다면 나머지 모든 항목들은 그에 맞게 교차축을 따라 늘어나게 됩니다.

다음의 라이브 예시를 통해 어떻게 보여지는지 확인할 수 있습니다. flexbox의 초기 동작을 시험해보려면 항목을 추가하거나 수정해보시기 바랍니다.

### flex-direction 지정

**flex 컨테이너**에 `flex-direction` 속성을 지정하면 flex 항목이 나열되는 방향을 변경할 수 있습니다. `flex-direction: row-reverse` 라고 지정하면 행으로 나열되는 것은 그대로지만 시작 선과 끝 선이 서로 바뀌게 됩니다.

`flex-direction`을 `column`으로 지정하면 주축이 변경되고 항목들은 열로 나열됩니다. `column-reverse`로 지정하면 그에 더해 시작 선과 끝 선이 서로 바뀌게 됩니다.

다음의 라이브 예시는 `flex-direction`이 `row-reverse`로 지정되어 있습니다. `row`, `column`, `column-reverse`와 같은 값을 지정해서 어떻게 되는지 확인해보시기 바랍니다.

flex-wrap을 이용한 복수 행 flex 컨테이너 지정
--------------------------------

flexbox는 1차원 모델이지만 **flex 항목**이 여러 행에 나열되도록 할 수 있습니다. 그 경우 각 행이 새로운 **flex 컨테이너**라고 생각해야 합니다. 공간 배분은 해당 행에서만 이루어지며 다른 행은 영향을 받지 않습니다.

항목이 여러 행에 나열되도록 하려면 `flex-wrap` 속성의 값을 `wrap`으로 지정합니다. 그러면 항목이 하나의 행에 들어가지 않을 정도로 클 경우 다른 행에 배치됩니다. 아래의 라이브 예시에 있는 **flex 항목**은 폭이 지정되어 있으며 항목들의 폭의 합은 **flex 컨테이너**에 들어가기에는 너무 넓습니다. `flex-wrap`속성이 `wrap`으로 지정되어 있으므로 항목은 여러 행에 나열됩니다. 초깃값과 동일한 `nowrap`을 지정하고 flex항목에 대한 확대/축소 방식을 별도로 지정하지 않으면 **flex 항목**들은 컨테이너의 폭에 맞게 줄어듭니다. `nowrap`을 지정하면 항목이 전혀 줄어들 수 없거나 충분히 줄어들 수 없을 때 흘러넘치게 됩니다.

Mastering Wrapping of Flex Items (en-US) 가이드에서 더 자세한 내용을 확인할 수 있습니다.

축약형 속성 flex-flow
----------------

`flex-direction` 속성과 `flex-wrap` 속성을 `flex-flow`라는 축약 속성으로 합칠 수 있습니다. 첫 번째 값은 `flex-direction`이고 두 번째 값은 `flex-wrap`입니다.

다음의 라이브 예시에서 첫 번째 값을 `flex-direction`에 지정 가능한 값들(`row`, `row-reverse`, `column` or `column-reverse`)로 바꿔보시기 바랍니다. 두 번째 값도 `wrap`이나 `nowrap`으로 바꿔보시기 바랍니다.

flex 항목에 지정 가능한 속성들
-------------------

**flex 항목**에 적용할 수 있는 속성은 다음과 같습니다.

* `flex-grow`
* `flex-shrink`
* `flex-basis`

이 글에서는 위의 속성들에 대해 간략하게 살펴보겠습니다. 자세한 내용은 Controlling Ratios of Flex Items on the Main Axis (en-US)에서 다룹니다.

500 픽셀의 크기를 갖는 **flex 컨테이너** 내에 100 픽셀 크기의 자식 세 개가 존재할 때, **사용가능한 공간** 200 픽셀이 남게 됩니다. 기본적으로 flexbox는 이 공간을 마지막 자식 요소 다음에 빈공간으로 남겨둡니다.

![This flex container has available space after laying out the items.](/ko/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox/basics7.png)

위의 세 가지 속성을 변경한다는 것은 **flex 항목**에게 **사용가능한 공간**을 분배하는 방식을 변경하는 것입니다. **사용가능한 공간** 개념은 **flex 항목**을 정렬할 때 특히 중요합니다.

### `flex-basis` 속성

`flex-basis` 속성은 항목의 크기를 결정합니다. 이 속성의 기본값은 `auto`이며, 이 경우 브라우저는 항목이 크기를 갖는지 확인합니다. 위의 사진 예시의 경우 항목의 크기가 100 픽셀이므로 flex-basis의 값으로 100 픽셀이 사용됩니다.

**flex 항목**에 크기가 지정되어 있지 않으면, **flex 항목**의 내용물 크기가 flex-basis 값으로 사용됩니다. 따라서 **flex 컨테이너**에서 `display: flex` 속성만을 지정하면 flex항목들이 각 내용물 크기만큼 공간을 차지하게 됩니다.

### `flex-grow` 속성

`flex-grow`값을 양수로 지정하면 **flex 항목**별로 주축 방향 크기가 `flex-basis` 값 이상으로 늘어날 수 있게 됩니다. 위의 사진 예시에서 모든 항목의 flex-grow 값을 1로 지정하면 사용가능한 공간은 각 항목에게 동일하게 분배되며, 각 항목은 주축을 따라 분배받은 값만큼 사이즈를 늘려 공간을 차지합니다.

첫 항목의 `flex-grow` 값을 2로 지정하고 나머지 두 개의 항목을 1로 지정한다면 각 항목에 지정된 `flex-grow` 값의 비율에 따라 남은 공간이 분배됩니다. 각 항목의 `flex-grow` 비율이 2:1:1 이므로 첫 항목에게 100 픽셀, 두 번째와 세 번째 항목에게 50 픽셀씩 분배됩니다.

### `flex-shrink` 속성

`flex-grow` 속성이 주축에서 남는 공간을 항목들에게 분배하는 방법을 결정한다면 `flex-shrink` 속성은 주축의 공간이 부족할때 각 항목의 사이즈를 줄이는 방법을 정의합니다. 만약 **flex 컨테이너**가 **flex 항목**을 모두 포함할 만큼 넉넉한 공간을 갖고 있지 않고 `flex-shrink` 값이 양수이면 **flex 항목**은 flex-basis에 지정된 크기보다 작아집니다. 또한, `flex-grow` 속성과 마찬가지로 더 큰 `flex-shrink` 값을 갖는 항목의 사이즈가 더 빨리 줄어듭니다.

항목의 최소 크기는 실제 축소량을 계산할 때 고려되기 때문에 flex-shrink 속성이 flex-grow 속성에 비해 덜 일관된 모습을 보여줄지도 모릅니다. `flex-shrink` 속성이 항목의 사이즈를 결정하는 알고리즘에 관해서는 Controlling Ratios of Flex Items on the Main Axis (en-US)에서 자세히 살펴히보겠습니다.

**참고:** `flex-grow` 와 `flex-shrink`의 값이 비율임을 유의하세요. **flex 항목**의 flex 속성을 모두 `1 1 200px` 로 지정하고 한 항목만 크기가 늘어나는 비율을 타 항목의 두배로 하고 싶으면 해당 **flex 항목**의 flex 속성을 `2 1 200px`로 지정하면 되지만, flex 속성 값을 모두 `10 1 200px`로 지정하고 늘어나는 비율을 두 배로 하고 싶은 항목의 flex 속성 값만 `20 1 200px`로 지정해도 동일하게 동작합니다.

### 축약형 속성 flex

보통은 `flex-grow`, `flex-shrink`, `flex-basis` 값을 각각 사용하지 않고 이 세 속성을 한번에 지정하는 `flex` 축약형을 많이 사용합니다. `flex` 축약형의 값은 `flex-grow`, `flex-shrink`, `flex-basis` 순서로 지정됩니다.

다음의 라이브 예시에서 flex 축약형의 값들을 조절하면서 시험해 볼 수 있습니다. 첫 값이 `flex-grow`를 지정하며, 이 첫 값을 양수로 하면 **flex 항목**이 넓어질 수 있습니다. 두 번째 값은 `flex-shrink` 를 지정하며 이 두 번째 값에 양수를 지정하면 **flex 항목**이 좁아질 수 있습니다. 세 번째 값은 `flex-basis`를 지정하며 이 값은 **flex 항목**이 넓어지거나 좁아질 때 고려하는 기준 값입니다.

flex 축약형 표현에 사용할 수 있는 미리 정의된 축약 값들이 아래에 나열되어 있습니다. 이 값들 만으로도 대부분의 경우(use-case)에 대응할 수 있을 것 입니다.

* `flex: initial`
* `flex: auto`
* `flex: none`
* `flex: <positive-number>`

**flex 항목**을 `flex: initial`로 지정하면 `flex: 0 1 auto` 로 지정한 것과 동일하게 동작합니다. 이 경우, **flex 항목**들은 `flex-grow`가 0이므로 `flex-basis`값보다 커지지 않고 `flex-shrink`가 1이므로 **flex 컨테이너** 공간이 모자라면 크기가 줄어듭니다. 또, `flex-basis`가 `auto`이므로 **flex 항목**은 주축 방향으로 지정된 크기 또는 자기 내부 요소 크기 만큼 공간을 차지합니다.

`flex: auto` 로 지정하면 `flex: 1 1 auto`로 지정한 것과 동일하며, `flex:initial` 과는 주축 방향 여유 공간이 있을 때 **flex 항목**들이 늘어나서 주축 방향 여유 공간을 채우는 점만 다릅니다.

`flex: none`으로 지정하면 `flex: 0 0 auto`으로 지정한 것과 동일하며 **flex 컨테이너**의 크기 변화에도 **flex 항목** 크기는 변하지 않고 `flex-basis`를 `auto`로 지정했을 때 정해지는 크기로 결정됩니다.

이 축약형은 더 축약해서 `flex: 1` 이나 `flex: 2`처럼 쓸수도 있는데, 이는 `flex-grow` 만 지정하고 나머지는 1 0으로 사용한다는 뜻이다. 따라서 `flex: 2`는 `flex: 2 1 0`와 동일하게 처리됩니다.

다음 라이브 예제에서 이 축약 값들을 시험해 볼 수 있습니다.

정렬, 끝 맞추기(justification), flex 항목간 여유 공간 분배
-------------------------------------------

flexbox의 주 기능 중 하나는 (주축과 교차축으로 표현되는) **flex 컨테이너** 공간 안에 **flex 항목**들을 정렬하고 끝 마추며 여유 공간을 항목 간에 분배하는 것입니다.

역주) 이 절의 내용은 편의상 **flex 컨테이너**의 flex-direction를 row로 가정하고 '행'과 '열'로 표기했습니다.

### `align-items`

`align-items` (en-US)는 **flex 컨테이너**에 지정하는 속성이며, 교차축을 따라 **flex 항목** 열을 정렬하는 방식을 지정합니다.

이 속성의 (아무것도 지정하지 않았을 때 적용되는)초기 값은 `stretch`이며 이 값을 지정하면 **flex 항목**의 높이는 **flex 컨테이너** 내 **flex 항목** 행의 최대 높이로 지정됩니다. 따라서, **flex 항목** 행이 하나 일 때는 **flex 항목**은 교차축 방향으로 **flex 컨테이너**를 가득 채우게 됩니다.

이 속성을 `flex-start`로 지정하면 **flex 항목**의 첫 열이 교차축 방향의 시작선에 정렬됩니다. `flex-end`로 지정하면 **flex 항목**의 첫 열이 교차축 방향의 끝선에 정렬됩니다. `center`로 지정하면 **flex 항목** 행에 배분된 공간의 가운데 라인에 정렬됩니다.

다음 라이브 예제에서 이 값들을 시험해 볼 수 있습니다. - 이 시험을 위해 의도적으로 **flex 컨테이너**에 높이를 지정해 두었습니다.

* `stretch`
* `flex-start`
* `flex-end`
* `center`

### `justify-content`

`justify-content` 속성은 주축을 따라 **flex 항목** 행을 정렬하는 방식을 지정합니다.

이 속성의 (아무것도 지정하지 않았을 때 적용되는)초기 값은 `flex-start`이며 이 값을 지정하면 **flex 항목** 행 내의 항목들은 **flex 컨테이너**의 시작선에서 부터 정렬됩니다. `flex-end`로 지정하면 **flex 항목** 행의 마지막 항목이 **flex 컨테이너**의 끝선에서 정렬됩니다. `center`로 지정하면 **flex 항목**들이 **flex 항목** 행의 가운데 정렬됩니다.

`space-between`을 지정하면 주축 방향 여유 공간을 **flex 항목** 사이의 공간에 균등 배분합니다.

`space-around`는 시작선 및 끝선과 **flex 항목**간 공간도 균등 배분에 고려하므로 시작선 및 끝선과 **flex 항목** 간의 공간의 크기를 1로 배분한다면 **flex 항목** 사이의 공간은 2로 배분합니다.

`space-evenly`로 지정하면 여유 공간을 **flex 항목** 사이의 공간 및 시작선 및 끝선과 **flex 항목** 간의 공간에 모두 균등하게 배분합니다.

다음 라이브 예제에서 `justify-content`에 지정할 수 있는 다음 값들을 시험해 볼 수 있습니다.

* `stretch`
* `flex-start`
* `flex-end`
* `center`
* `space-around`
* `space-between`
* `space-evenly`

이 절에서 설명한 내용으로 대부분의 경우에 대응할 수 있지만, Aligning Items in a Flex Container 에서 이 속성들을 더 자세히 살펴볼 것입니다.

Next steps
----------

Flexbox의 개요를 살펴보았습니다. 다음 글 how this specification relates to other parts of CSS (en-US)에서 이 규격이 다른 CSS 규격과 어떻게 연관되어 있는지 말씀드리겠습니다.


플렉스박스의 대표적인 사용례 - CSS: Cascading Style Sheets

플렉스박스의 대표적인 사용례
===============

이번 안내서에서는 흔히 볼 수 있는 플렉스박스 사용 사례 중 일부를 살펴 보겠습니다. 플렉스박스의 사용이 다른 레이아웃 메서드보다 더 적합한 사례입니다.

왜 플렉스박스를 선택?
------------

완벽한 브라우저 지원 환경에서 플렉스박스를 사용하기로 선택한 이유는 항목 모음을 한 방향 또는 다른 방향으로 배치하길 원하기 때문입니다. 우리가 항목을 배치할 때 해당 일차원의 항목 크기를 제어하거나 항목 간 간격을 제어하려고 합니다. 이것이 플렉스박스를 설계한 목적에 맞는 용도입니다. 플렉스박스와 여타 CSS 레이아웃 메서드의 관계 (en-US)에서 플렉스박스와 CSS 격자 레이아웃의 차이점에 대해 자세히 읽을 수 있습니다. 그곳에선 플렉스박스가 CSS 레이아웃의 전체 그림에서 어떤 역할을 하고 있는지에 대해 논의합니다.

실제로 격자 레이아웃에 의해 더 잘 수행 될 수있는 작업이나 격자에 대한 대체품 및 정렬 기능을 얻기 위해 플렉스박스를 종종 사용합니다. 당 사용례는 블록 레이아웃에서 *상자 정렬* (Box Alignment) 이 구현되고 나면 변경될 수 있습니다. 이 안내서에서는 오늘날 플렉스박스가 쓰일 수 있는 몇 가지 대표적인 사용례를 살펴봅니다.

탐색 메뉴
-----

탐색 메뉴의 일반적인 패턴은 항목 목록을 가로 막대로 표시하는 것입니다. 이 패턴은 기본적으로 플렉스박스 이전에는 달성하기 어려웠습니다. 이는(탐색 가로 막대) 가장 간단한 플렉스박스 예제를 형성하며 이상적인 플렉스박스 사용 사례로 간주될 수 있습니다.

가로로 표시하려는 항목 집합이 있으면 잉여 공간이 생길 수밖에 없습니다. 우리는 그 공간으로 무엇을 해야할지 결정해야 하며 몇 가지 선택 옵션이 있습니다. 일번 선택은 우리가 항목 무리 이외의 공간을 표시합니다. 따라서 그 사이 또는 그 주변에 공백이 생깁니다. 또는 항목 내부 여분의 공간을 흡수하려면 항목 집합이 이 공간을 확장하고 점유할 수 있는 메소드가 필요합니다.

### 항목 외부에 공간 분배

항목 사이 또는 주위에 공간을 분배시키기 위해 플렉스박스의 정렬 속성과 `justify-content` 속성을 사용합니다. 이 속성에 대한 자세한 내용은 기본 축을 기준으로 항목 정렬을 처리하는 가변 컨테이너의 항목 정렬에서 확인할 수 있습니다.

아래 실제 예에서 우리는 항목을 원래 크기로 표시하고 `justify-content: space-between`를 사용하여 항목 사이의 간격을 동일하게 만듭니다. `space-around` 값을 사용하거나, 지원이 될 경우 `space-evenly`를 사용해 공간이 분배되는 방식을 변경할 수 있습니다. `flex-start`를 사용하여 항목 끝에 공간을 배치하거나 `flex-end`를 사용하여 항목 앞에 배치하거나 `center`를 사용해 탐색 항목 중앙에 배치할 수 있습니다.

### 항목 내부에 공간 분배

탐색 메뉴를 위한 다른 패턴은 항목 사이에 공간을 만드는 것이 아니라 항목 자체 내에 사용 가능한 공간을 분배하는 것입니다. 이 경우, 주축을 따라 가변 항목의 비율 제어 (en-US)에서 설명된대로 가변 속성을 사용하여 항목이 서로 비례하여 확대 및 축소되도록 합니다.

모든 탐색 메뉴 항목의 너비를 동일하게 하려면 `flex: auto`를 사용하면 됩니다. 그것은 `flex: 1 1 auto`의 약칭으로 모든 항목이 자동이란 가변 기반에 따라 확대되거나 축소됩니다. 여기서 자동이란 항목이 길수록 더 많은 공간이 생긴다는 말입니다.

아래의 실제 예제에서 `flex: auto`를 `flex: 1`로 변경해보십시요. 이것은 `flex: 1 1 0`의 약칭입니다. 모든 항목이 0의 가변 기반에서 작동하여 모든 공간을 고르게 배분할 수 있기 때문에 모든 항목이 동일한 너비가 됩니다.

탐색 메뉴 분할
--------

주축에서 항목을 정렬하는 또 다른 방법은 자동 여백을 사용하는 것입니다. 이를 통해 한 그룹의 항목이 왼쪽으로 정렬되고 다른 그룹이 오른쪽으로 정렬되는 탐색 모음(메뉴)의 디자인 패턴이 가능합니다.

여기에서는 주축 정렬에 대한 자동 여백 사용에서 설명된 자동 여백 기술을 사용합니다. 항목 무리는 `flex-start`를 사용해 주축에 정렬됩니다. 그것이 플렉스박스의 초기값 동작이며, 우리가 항목을 오른쪽으로 정렬하려면 왼쪽 여백을 자동으로 지정합니다. 클래스 지정을 한 항목에서 다른 항목으로 이동하여 분할이 발생하는 위치를 변경할 수 있습니다.

또한 이 예제에서는 가변 항목에 여백을 사용하여 항목 사이에 간격을 만들고 컨테이너에 음의 여백을 사용하여 항목이 여전히 오른쪽 및 왼쪽 가장자리와 맞붙도록 합니다. *박스 정렬* (Box Alignment) 규격의 `gap` 속성이 플렉스박스에 구현될 때까지 항목 간에 배수구를 만들려면 이 방식으로 여백을 사용해야 합니다.

항목 중심에 놓기
---------

플렉스박스 이전에 개발자들은 웹 디자인에서 가장 어려운 문제는 수직 중심이라고 농담할겁니다. 다음 실제 예제에서 볼 수 있듯이 플렉스박스의 정렬 속성을 사용하여 간단하게 만들었습니다.

항목에 `flex-start`를 지정해 시작 부분으로 정렬하거나 `flex-end`를 지정해 끝 부분에 항목을 정렬하는 식으로 정렬을 맘대로 조정할 수 있습니다.

*박스 정렬* (Box Alignment) 속성은 궁극적으로 블록 레이아웃의 내용으로 구현될 예정이므로 미래에는 단일 아이템을 중앙에 배치하기 위해 컨테이너를 가변 컨테이너로 만들 필요는 없습니다. 그러나 당장은 하나의 것을 다른 것의 중심에 올바로 배치해야하는 경우 플렉스박스를 사용하는 게 맞습니다. 위의 예에서와 같이 컨테이너를 가변 컨테이너로 만든 다음 상위 요소에 대해 `align-items`을 사용하거나 가변 항목 자체를 `align-self`로 공략합니다.

바닥글을 아래로 밀어내는 카드 레이아웃
---------------------

플렉스박스 또는 CSS 격자를 사용하여 카드 구성 요소의 목록을 레이아웃하더라도, 이들 레이아웃 메서드는 가변 또는 격자 구성 요소의 직계 자식에서만 작동합니다. 즉, 콘텐츠의 크기가 가변적이면 카드가 격자 영역의 높이나 가변 컨테이너의 높이까지 늘어납니다. 모든 내부 콘텐츠는 친숙한 블록 레이아웃을 사용합니다. 즉, 콘텐츠가 적은 카드에서는 바닥글이 카드의 아래쪽에 고정되지 않고 콘텐츠의 밑단까지 차오릅니다.

![구성 요소의 내부가 (상위) 랩퍼와 함께 늘어나지 않음을 표시하는 두 개의 카드 구성 요소.](/ko/docs/Web/CSS/CSS_flexible_box_layout/Typical_use_cases_of_flexbox/flex-cards.png)

플렉스박스가 이를 해결할 수 있습니다. 우리는 `flex-direction``: column` 속성를 가진 카드를 가변 컨테이너로 만듭니다. 그런 다음 컨텐츠 영역을 `flex: 1`로 설정합니다. 이는 `flex: 1 1 0`의 축약형입니다. — 항목이 `0`의 가변 기준에서 커지거나 줄어들 수 있습니다. 이것이(컨텐츠 영역이) 커질 수 있는 유일한 항목이므로 가변 컨테이너에 있는 잉여 공간을 차지하고 바닥글을 바닥으로 밉니다. 라이브 예제에서 `flex` 속성을 제거하면 바닥글이 컨텐츠 바로 아래로 이동하는 방식을 볼 수 있습니다.

미디어 객체
------

미디어 객체는 웹 디자인에서 일반적인 패턴입니다. 이 패턴에는 한쪽에 이미지 나 다른 요소가 있고 오른쪽에 텍스트가 있습니다. 이상적으로 미디어 개체를 반대쪽으로 돌릴 수 있어야 합니다. 말하자면 이미지를 왼쪽에서 오른쪽으로 이동시키는 겁니다.

이 패턴은 어디에서나 볼 수 있으며, 주석 상자용으로 쓰이기도 하고, 이미지와 설명을 표시해야하는 모든 곳에서 볼 수 있습니다. 플렉스박스를 사용하면 이미지를 포함하는 미디어 객체의 일부가 이미지에서 크기 정보를 가져온 다음 미디어 객체의 본문이 가변적으로 남은 공간을 차지할 수 있습니다.

여러분은 아래 실제 예제에서 미디어 객체를 볼 수 있습니다. 정렬 속성을 사용하여 십자축의 항목을 `flex-start`로 정렬한 다음 `.content` 가변 항목을 `flex: 1`로 설정했습니다. 위의 열 레이아웃 카드 패턴에서와 같이 `flex: 1`를 사용하면 카드가 커질 수 있습니다.

이 라이브 예제에서 시도할 수 있는 것은 디자인에서 미디어 개체를 제약하려는 여러 가지 방법과 관련이 있습니다.

이미지가 너무 커지는 것을 방지하려면 이미지에 `max-width`를 추가하십시오. 미디어 객체의 그쪽 측면이 플렉스박스의 초기값(예: 100px)을 사용함에 따라 줄어들지만 커질 수는 없으며 `flex-basis`는 자동을 사용합니다. 이미지에 적용된 모든 `width` 또는 최대 너비는 `flex-basis` (가변 기준) 이 됩니다.

```css
.image img {
  max-width: 100px;
}
```

또한 양쪽이 비례하여 커지거나 줄어들 수 있습니다. 양면을 `flex: 1`로 설정하면 0의 `flex-basis`에서 커지거나 줄어들기 때문에 두 개의 동일한 크기의 열이 생깁니다. 컨텐츠를 기준으로 사용하여 (컨텐츠와 이미지) 둘 다에 `flex: auto`로 설정하면 컨텐츠의 크기에 따라, 또는 이미지의 너비와 같은 가변 항목에 직접 적용되는 크기에 따라 커지거나 줄어들 수 있습니다.

```css
.media .content {
  flex: 1;
  padding: 10px;
}

.image {
  flex: 1;
}
```

예를 들어 이미지가 있는 쪽을 `flex: 1`로 설정하고 콘텐츠 쪽을 `flex: 3`으로 설정하는 등 각면에 서로 다른 `flex-grow`를 부여할 수 있습니다. 즉, `flex-basis`를 `0`으로 사용하지만 해당 공간을 `flex-grow` 인수에 맞춰 서로 다르게 공간을 할당합니다. 그런 용도로 사용하는 가변 속성은 주축을 따라 가변 항목의 비율 제어 (en-US) 안내서에서 자세히 설명되어 있습니다.

```css
.media .content {
  flex: 3;
  padding: 10px;
}

.image {
  flex: 1;
}
```

### 미디어 객체 방향 돌리기

이미지가 오른쪽에 있고 콘텐츠가 왼쪽에 있도록 미디어 객체의 표시를 전환하려면 `flex-direction` 속성을 이용해 `row-reverse`로 설정할 수 있습니다. 미디어 개체가 이제 다른 방향으로 표시됩니다. 저는 그걸 달성하기 위해 라이브 예제에서 기존 `.media` 클래스와 함께 `flipped` 클래스를 추가했습니다. 즉, HTML에서 해당 클래스를 제거하여 디스플레이가 어떻게 변경되는지 확인할 수 있습니다.

양식 컨트롤
------

플렉스박스는 양식 컨트롤에 스타일을 적용할 때 특히 유용합니다. 양식에는 일반적으로 서로 정렬하고 싶은 다수의 마크업과 다수의 작은 요소를 포함할 수 있습니다. 일반적인 패턴은 `<input>` (en-US) 요소가 `<button>`과 짝을 이루는 검색 양식의 경우나 방문자가 단순히 전자 메일 주소를 입력하도록 하려는 경우입니다.

플렉스박스를 사용하면 이러한 유형의 레이아웃을 쉽게 달성할 수 있습니다. 테두리를 지정하고 표시하도록 설정한 래퍼 클래스에 `<button>` 및 `<input>` 필드가 포함되어 있습니다. 거기에 테두리를 부여하고 `display: flex`를 설정했습니다. 그런 다음 가변 속성을 사용하여 `<input>` 필드가 커지도록 했고, 버튼은 그렇지 않습니다. 이것은 사용 가능한 공간이 변함에 따라 텍스트 필드가 커지거나 작아지는 한 쌍의 필드가 있음을 의미합니다.

버튼을 오른쪽에 올려 놓은 것처럼 레이블이나 아이콘을 왼쪽에 쉽게 추가 할 수 있습니다. 나는 레이블을 추가했으며 배경색에 대한 스타일링 이외에 레이아웃을 변경할 필요가 없었습니다. 신축성있는 입력 필드는 이제 맘대로 이용할 공간이 조금 줄어들지만 두 항목의 지분이 고려된 후 남은 공간을 사용합니다.

이와 같은 패턴을 사용하면 디자인에 추가할 요소를 쉽게 수용할 수 있는 양식 요소 라이브러리를 훨씬 쉽게 만들 수 있습니다. 커지지 않는 항목과 커지는 항목을 혼합하는 식으로 플렉스박스의 유연성을 활용하고 있습니다.

결론
--

위의 패턴을 살펴보면서 플렉스박스를 사용하여 원하는 결과를 얻는 가장 좋은 방법을 여러분이 생각을 통해 파악되기 시작했길 희망해봅니다. 종종 하나 이상의 선택이 있습니다. 늘릴 수 없는 항목을 늘릴 수 있는 것과 혼합하거나, 콘텐츠를 사용하여 크기를 알리거나, 플렉스박스가 공간을 비례적으로 공유할 수 있도록 하십시오. 그것은 당신에게 달려 있습니다.

보유 컨텐츠를 제시하는 가장 좋은 방법을 생각한 다음 플렉스박스 또는 기타 레이아웃 방법이 컨텐츠를 선보이는 데 어떻게 도움이 되는지 살펴보십시오.


Aligning Items in a Flex Container - CSS: Cascading Style Sheets

Aligning Items in a Flex Container
==================================

flexbox가 웹 개발자들의 관심 받게된 이유 중 하나는 웹 최초로 최초로 적절한 정렬 기능을 제공했기 때문입니다. flexbox의 수직 정렬 기능을 이용하여 우리는 드디어 쉽게 박스(역주: 여기서 박스는 **flex 컨테이너**를 의미합니다) 내부를 중앙 정렬 할 수 있게 되었습니다. 이 가이드에서 우리는 flexbox의 정렬 및 끝 맞추기 기능에 대해 자세히 살펴볼 것입니다.

박스 내부를 중앙 정렬 하기 위해 박스에 `align-items` 속성을 지정하면 교차 축에 대해 flex 항목을 정렬할 수 있습니다. 아래 경우, 교차 축은 수직 축입니다. `justify-content` 속성을 지정하면 flex 항목을 주축에 대해 정렬 할 수 있습니다. 아래 경우, 주축은 수평 방향입니다.

![A containing element with another box centered inside it.](/ko/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align1.png)

아래 예제의 코드를 살펴보세요. flex 컨테이너(역주: .box로 지정된 div 태그)나 flex 항목(역주: .box div로 지정된 div 태그)의 크기를 조절해도 flex 컨테이너 내부는 중앙 정렬됨을 보실 수 있습니다.

정렬 제어용 속성 목록
------------

이 글에서 살펴볼 속성들은 다음과 같습니다.

* `justify-content` — 주축에 대해 flex 항목들을 정렬하는 방식을 제어. flex 컨테이너에 지정하는 속성.
* `align-items` (en-US) — 교차축에 대해 flex 항목들을 정렬하는 방식을 제어. flex 컨테이너에 지정하는 속성.
* `align-self` (en-US) — 개별 flex 항목을 교차 축에 대해 정렬 하는 방식을 제어. flex 항목에 지정하는 속성.
* `align-content` — described in the spec as for "packing flex lines"; controls space between flex lines on the cross axis.

또한, 이글에서 flexbox기반 정렬에서 margin 속성 값이 어떨게 쓰이는지 살펴볼 것입니다.

**참고:** The alignment properties in Flexbox have been placed into their own specification — CSS Box Alignment Level 3. It is expected that this spec will ultimately supersede the properties as defined in Flexbox Level One.

교차축
---

`align-items`와 `align-self` 속성들은 flex 항목들을 교차축으로 정렬하는 것을 제어합니다. 만약, `flex-direction`이 `row`로 설정되어있다면 열 (column) 아래로 정렬을 하게되고, `flex-direction`이 `column`으로 설정되어있다면 행 (row)을 따라 정렬됩니다.

가장 간단한 flex예시는 교차축을 이용합니다. `display: flex`를 컨테이너에 추가하게되면, 모든 자식 항목들이 열 (row), 즉 가로 방향으로 정렬이 되는 flex 항목이 됩니다. 이 경우 가장 큰 y축의 크기, 즉 높이가 가장 큰 자식 항목이 교차축의 높이를 정의하게 되고, 나머지 자식 항목들은 이 높이에 맞추어 높이가 늘어나게 됩니다. 만약 flex 컨테이너의 높이가 지정이 되어있다면, 자식 항목 내용에 상관없이 지정된 높이 만큼 모든 자식 항목들이 늘어나게됩니다.

![Three items, one with additional text causing it to be taller than the others.](/ko/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align2.png)

![Three items stretched to 200 pixels tall](/ko/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align3.png)

모든 항목들이 같은 높이를 갖게되는 이유는 교차축을 중심으로 정렬을 제어하는 속성인 `align-items`에 지정된 초기값이 `stretch`로 설정이 되어있기 때문입니다.

이외에도 다른 값을 지정해서 항목들이 정렬되는 방식을 다르게 정의 할 수 있습니다:

* `align-items: flex-start`
* `align-items: flex-end`
* `align-items: center`
* `align-items: stretch`
* `align-items: baseline`

아래의 예시를 보면, `align-items`값이 `stretch`로 지정이 되어있습니다. 여기에 다른 값들을 넣어서 항목들이 flex 컨테이너 안에서 어떻게 정렬이 되는지 확인해보세요.

### `align-self`로 항목 한 개를 정렬하기

The `align-items` property sets the `align-self` property on all of the flex items as a group. This means you can explicitly declare the `align-self` property to target a single item. The `align-self` property accepts all of the same values as `align-items` plus a value of `auto`, which will reset the value to that which is defined on the flex container.

In this next live example, the flex container has `align-items: flex-start`, which means the items are all aligned to the start of the cross axis. I have targeted the first item using a `first-child` selector and set that item to `align-items: stretch`; another item has been selected using its class of `selected` and given `align-self: center`. You can change the value of `align-items` or change the values of `align-self` on the individual items to see how this works.

### Changing the main axis

So far we have looked at the behaviour when our `flex-direction` is `row`, and while working in a language written top to bottom. This means that the main axis runs along the row horizontally, and our cross axis alignment moves the items up and down.

![Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the vertical axis.](/ko/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align4.png)

If we change our `flex-direction` to column, `align-items` and `align-self` will align the items to the left and right.

![Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the horizontal axis.](/ko/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align5.png)

You can try this out in the example below, which has a flex container with `flex-direction: column` yet otherwise is exactly the same as the previous example.

Aligning content on the cross axis — the align-content property
---------------------------------------------------------------

So far we have been aligning the items, or an individual item inside the area defined by the flex-container. If you have a wrapped multiple-line flex container then you might also want to use the `align-content` property to control the distribution of space between the rows. In the specification this is described as packing flex lines.

For `align-content` to work you need more height in your flex container than is required to display the items. It then works on all the items as a set, and dictates what happens with that free space, and the alignment of the entire set of items within it.

The `align-content` property takes the following values:

* `align-content: flex-start`
* `align-content: flex-end`
* `align-content: center`
* `align-content: space-between`
* `align-content: space-around`
* `align-content: stretch`
* `align-content: space-evenly` (not defined in the Flexbox specification)

In the live example below, the flex container has a height of 400 pixels, which is more than needed to display our items. The value of `align-content` is `space-between`, which means that the available space is shared out *between* the flex lines, which are placed flush with the start and end of the container on the cross axis.

Try out the other values to see how the `align-content` property works.

Once again we can switch our `flex-direction` to `column` in order to see how this property behaves when we are working by column. As before, we need enough space in the cross axis to have some free space after displaying all of the items.

**참고:** the value `space-evenly` is not defined in the flexbox specification and is a later addition to the Box Alignment specification. Browser support for this value is not as good as that of the values defined in the flexbox spec.

See the documentation for `justify-content` on MDN for more details on all of these values and browser support.

Aligning content on the main axis
---------------------------------

Now that we have seen how alignment works on the cross axis, we can take a look at the main axis. Here we only have one property available to us — `justify-content`. This is because we are only dealing with items as a group on the main axis. With `justify-content` we control what happens with available space, should there be more space than is needed to display the items.

In our initial example with `display: flex` on the container, the items display as a row and all line up at the start of the container. This is due to the initial value of `justify-content` being `flex-start`. Any available space is placed at the end of the items.

![Three items, each 100 pixels wide in a 500 pixel container. The available space is at the end of the items.](/ko/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align6.png)

The `justify-content` property accepts the same values as `align-content`.

* `justify-content: flex-start`
* `justify-content: flex-end`
* `justify-content: center`
* `justify-content: space-between`
* `justify-content: space-around`
* `justify-content: stretch`
* `justify-content: space-evenly` (not defined in the Flexbox specification)

In the example below, the value of `justify-content` is `space-between`. The available space after displaying the items is distributed between the items. The left and right item line up flush with the start and end.

If the main axis is in the block direction because `flex-direction` is set to `column`, then `justify-content` will distribute space between items in that dimension as long as there is space in the flex container to distribute.

### Alignment and Writing Modes

Remember that with all of these alignment methods, the values of `flex-start` and `flex-end` are writing mode-aware. If the value of `justify-content` is `start` and the writing mode is left-to-right as in English, the items will line up starting at the left side of the container.

![Three items lined up on the left](/ko/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/basics5.png)

However if the writing mode is right-to-left as in Arabic, the items will line up starting at the right side of the container.

![Three items lined up from the right](/ko/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/basics6.png)

The live example below has the `direction` property set to `rtl` to force a right-to-left flow for our items. You can remove this, or change the values of `justify-content` to see how flexbox behaves when the start of the inline direction is on the right.

Alignment and flex-direction
----------------------------

The start line will also change if you change the `flex-direction` property — for example using `row-reverse` instead of `row`.

In this next example I have items laid out with `flex-direction: row-reverse` and `justify-content: flex-end`. In a left to right language the items all line up on the left. Try changing `flex-direction: row-reverse` to `flex-direction: row`. You will see that the items now move to the right hand side.

While this may all seem a little confusing, the rule to remember is that unless you do something to change it, flex items lay themselves out in the direction that words are laid out in the language of your document along the inline, row axis. `flex-start` will be where the start of a sentence of text would begin.

![Diagram showing start on the left and end on the right.](/ko/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align8.png)

You can switch them to display in the block direction for the language of your document by selecting `flex-direction: column`. Then `flex-start` will then be where the top of your first paragraph of text would start.

![Diagram showing start at the top and end at the bottom.](/ko/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align10.png)

If you change flex-direction to one of the reverse values, then they will lay themselves out from the end axis and in the reverse order to the way words are written in the language of your document. `flex-start` will then change to the end of that axis — so to the location where your lines would wrap if working in rows, or at the end of your last paragraph of text in the block direction.

![Diagram showing start on the right and end on the left.](/ko/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align9.png)

![Diagram showing end at the top and start at the bottom](/ko/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align11.png)

Using auto margins for main axis alignment
------------------------------------------

We don't have a `justify-items` or `justify-self` property available to us on the main axis as our items are treated as a group on that axis. However it is possible to do some individual alignment in order to separate an item or a group of items from others by using auto margins along with flexbox.

A common pattern is a navigation bar where some key items are aligned to the right, with the main group on the left. You might think that this should be a use case for a `justify-self` property, however consider the image below. I have three items on one side and two on the other. If I were able to use `justify-self` on item *d*, it would also change the alignment of item *e* that follows, which may or may not be my intention.

![Five items, in two groups. Three on the left and two on the right.](/ko/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align7.png)

Instead we can target item 4 and separate it from the first three items by giving it a `margin-left` value of `auto`. Auto margins will take up all of the space that they can in their axis — it is how centering a block with margin auto left and right works. Each side tries to take as much space as it can, and so the block is pushed into the middle.

In this live example, I have flex items arranged simply into a row with the basic flex values, and the class `push` has `margin-left: auto`. You can try removing this, or adding the class to another item to see how it works.

Future alignment features for Flexbox
-------------------------------------

At the beginning of this article I explained that the alignment properties currently contained in the Level 1 flexbox specification are also included in Box Alignment Level 3, which may well extend these properties and values in the future. We have already seen one place where this has happened, with the introduction of the `space-evenly` value for `align-content` and `justify-content` properties.

The Box Alignment module also includes other methods of creating space between items, such as the `column-gap` and `row-gap` feature as seen in CSS Grid Layout. The inclusion of these properties in Box Alignment means that in future we should be able to use `column-gap` and `row-gap` in flex layouts too, and in Firefox 63 you will find the first browser implementation of the gap properties in flex layout.

My suggestion when exploring flexbox alignment in depth is to do so alongside looking at alignment in Grid Layout. Both specifications use the alignment properties as detailed in the Box Alignment specification. You can see how these properties behave when working with a grid in the MDN article Box Alignment in Grid Layout (en-US), and I have also compared how alignment works in these specifications in my Box Alignment Cheatsheet.

See Also
--------

* Box Alignment (en-US)
* Box Alignment in Flexbox (en-US)
* Box Alignment in Grid Layout (en-US)


CSS 애니메이션 사용하기 - CSS: Cascading Style Sheets

CSS 애니메이션 사용하기
==============

**실험적:** **이 기능은 실험적인 기능입니다.**
프로덕션 환경에서 사용하기 전에 브라우저 호환성 표를 주의 깊게 확인하세요.

**CSS3 애니메이션**은 엘리먼트에 적용되는 CSS 스타일을 다른 CSS 스타일로 부드럽게 전환시켜 줍니다. 애니메이션은 애니메이션을 나타내는 CSS 스타일과 애니메이션의 중간 상태를 나타내는 키프레임들로 이루어집니다.

CSS 애니메이션은 기존에 사용되던 스크립트를 이용한 애니메이션 보다 다음 세 가지 이유에서 이점을 가집니다.

1. JavaScript를 모르더라도 간단하게 애니메이션을 만들 수 있습니다.
2. JavaScript를 이용한 애니메이션은 잘 만들어졌더라도 성능이 좋지 못할때가 있습니다. CSS 애니메이션은 frame-skipping 같은 여러 기술을 이용하여 최대한 부드럽게 렌더링됩니다.
3. 브라우저는 애니메이션의 성능을 효율적으로 최적화할 수 있습니다. 예를 들어 현재 안보이는 엘리먼트에 대한 애니메이션은 업데이트 주기를 줄여 부하를 최소화할 수 있습니다.
애니메이션 적용하기
----------

CSS 애니메이션을 만드려면 `animation` 속성과 이 속성의 하위 속성을 지정합니다. 애니메이션의 총 시간과 반복 여부등을 지정할 수 있습니다. 이 속성은 애니메이션의 중간상태를 기술하지 않는다는걸 명심하세요. 애니메이션의 중간 상태는 아래에서 다룰 `@keyframes` 규칙을 이용하여 기술합니다.

`animation` 속성의 하위 속성은 다음과 같습니다.

`animation-delay`

엘리먼트가 로드되고 나서 언제 애니메이션이 시작될지 지정합니다.

`animation-direction`

애니메이션이 종료되고 다시 처음부터 시작할지 역방향으로 진행할지 지정합니다.

`animation-duration`

한 싸이클의 애니메이션이 얼마에 걸쳐 일어날지 지정합니다.

`animation-iteration-count` (en-US)

애니메이션이 몇 번 반복될지 지정합니다. `infinite`로 지정하여 무한히 반복할 수 있습니다.

`animation-name` (en-US)

이 애니메이션의 중간 상태를 지정합니다. 중간 상태는 `@keyframes` 규칙을 이용하여 기술합니다.

`animation-play-state` (en-US)

애니메이션을 멈추거나 다시 시작할 수 있습니다.

`animation-timing-function` (en-US)

중간 상태들의 전환을 어떤 시간간격으로 진행할지 지정합니다.

`animation-fill-mode`

애니메이션이 시작되기 전이나 끝나고 난 후 어떤 값이 적용될지 지정합니다.

키프레임을 이용하여 애니메이션의 중간상태 기술하기
---------------------------

애니메이션의 중간 상태를 기술해 봅시다. `@keyframes` 규칙을 이용해서 두개 이상의 중간 상태를 기술합니다. 각 중간 상태는 특정 시점에 엘리먼트가 어떻게 보일지 나타냅니다.

CSS 스타일을 이용해 중간 상태에 어떻게 보일지 정의했다면 이 중간 상태가 전체 애니메이션에서 언제 등장할 지 `<percentage>` 를 이용해 지정합니다. 0%는 애니메이션이 시작된 시점을 의미하고 100%는 애니메이션이 끝나는 시점을 의미합니다. 최소한 이 두 시점은 기술되어야 브라우저가 언제 애니메이션이 시작되고 끝나는지 알 수 있습니다. 0%와 100% 대신 `from` 과 `to`로 사용할 수도 있습니다.

시작 시점과 종료 시점 사이의 특정 시점에도 중간 상태를 지정할 수 있습니다.

예제
--

**참고:** **노트:** 다음 예제들은 애니메이션 CSS 속성에 접두어가 사용되지 않았습니다(역자: -webkit-, -moz- 등). 오래된 브라우저는 접두어가 필요합니다.

### 텍스트가 브라우저를 가로질러 움직이게 하기

다음 단순한 예제에서 `<p>` 엘리먼트가 브라우저 윈도우 오른쪽에서 왼쪽으로 가로질러 움직이는걸 볼 수 있습니다.

```css
p {
  animation-duration: 3s;
  animation-name: slidein;
}

@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}
```

`<p>` 엘리먼트에 지정한 CSS 규칙에서 `animation-duration` 속성을 통해 애니메이션의 총 길이는 3초로 지정했습니다. 또 애니메이션의 중간 상태들을 `@keyframes` 규칙을 사용하여 기술하고 이것들에게 slidein라는 이름을 붙였습니다. 그리고 p 엘리먼트에 slidein이라는 애니메이션을 지정했습니다.

CSS 애니메이션을 지원하지 않는 브라우저를 위하여 `<p>` 에 특정 스타일을 지정하고 싶다면 그러셔도 됩니다. 여기서도 그렇게 할 수 있으나 이 예제에서는 애니메이션 효과만을 보기위해 지정하지 않았습니다.

애니메이션의 중간 상태는 `@keyframes` 규칙을 이용하여 기술합니다. 이 경우에서는 두개의 중간 상태를 기술했습니다. 첫 번째 중간 상태는 애니메이션이 시작되고 나서 0% 시점에 (`from`키워드를 사용해도 됩니다) 왼쪽 마진을 100%로 지정하는 것입니다. 왼쪽 마진을 100%로 지정했으므로 애니메이션이 시작된 시점에 브라우저 윈도우 오른쪽 모서리에 엘리먼트가 그려집니다.

두번째 중간 상태는 애니메이션이 시작되고나서 100% (to키워드를 사용해도 됩니다)시점에 왼쪽 마진을 0%으로 지정하는 것입니다. 따라서 애니메이션 마지막에는 엘리먼트가 브라우저 윈도우의 왼쪽 모서리에 그려집니다.

```html
<p>
  The Caterpillar and Alice looked at each other for some time in silence: at
  last the Caterpillar took the hookah out of its mouth, and addressed her in a
  languid, sleepy voice.
</p>
```

### 중간 상태 추가하기

이전 예제의 애니메이션에서 중간 상태를 추가해 봅시다. 왼쪽에서 오른쪽으로 엘리먼트가 움직일 때 글자 크기가 커지다가 다시 원래대로 줄어들게 해봅시다. 다음과 같은 중간 상태를 추가하면 됩니다.

```css
75% {
  font-size: 300%;
  margin-left: 25%;
  width: 150%;
}
```

```
p {
  animation-duration: 3s;
  animation-name: slidein;
}

@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}
```

```
<p>
  The Caterpillar and Alice looked at each other for some time in silence: at
  last the Caterpillar took the hookah out of its mouth, and addressed her in a
  languid, sleepy voice.
</p>
```

애니메이션의 75% 시점에서 엘리먼트의 왼쪽 마진을 25%, 너비를 150%, 글자 크기를 300%로 지정하라는 의미입니다.

### 애니메이션 반복하기

애니메이션을 반복하고 싶다면 `animation-iteration-count` (en-US) 속성을 사용하면 됩니다. 이 속성으로 애니메이션이 몇 번 반복될지 지정할 수 있습니다. 이 예제에서는 `infinite` 라는 값을 지정하여 무한히 반복되게 해 봅시다.

```css
p {
  animation-duration: 3s;
  animation-name: slidein;
  animation-iteration-count: infinite;
}
```

```
@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}
```

```
<p>
  The Caterpillar and Alice looked at each other for some time in silence: at
  last the Caterpillar took the hookah out of its mouth, and addressed her in a
  languid, sleepy voice.
</p>
```

### 앞뒤로 움직이기

앞에서 애니메이션이 반복되는걸 보셨을 겁니다. 그런데 애니메이션이 끝나고 갑자기 오른쪽 모서리로 돌아가는게 어색합니다. 애니메이션이 끝났을 때 반대방향으로 이동하도록 만들어 봅시다. `animation-direction` 속성을 `alternate`로 지정하면 됩니다.

```css
p {
  animation-duration: 3s;
  animation-name: slidein;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}
```

```
@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}
```

```
<p>
  The Caterpillar and Alice looked at each other for some time in silence: at
  last the Caterpillar took the hookah out of its mouth, and addressed her in a
  languid, sleepy voice.
</p>
```

### 애니메이션 이벤트 사용하기

애니메이션 이벤트를 이용하여 애니메이션을 조종할 수 있습니다. `AnimationEvent` (en-US) 로 나타내어지는 애니메이션 이벤트를 사용하여 애니메이션의 시작, 끝, 새로운 반복의 시작등을 감지할 수 있습니다. 이벤트가 발생할 때마다 이벤트의 종류와 어떤 애니메이션에서 발생한 것인지 알 수도 있습니다.

위의 움직이는 글자 예제를 수정하여 애니메이션 이벤트를 어떻게 사용하는지 알아봅시다.

```css
.slidein {
  -moz-animation-duration: 3s;
  -webkit-animation-duration: 3s;
  animation-duration: 3s;
  -moz-animation-name: slidein;
  -webkit-animation-name: slidein;
  animation-name: slidein;
  -moz-animation-iteration-count: 3;
  -webkit-animation-iteration-count: 3;
  animation-iteration-count: 3;
  -moz-animation-direction: alternate;
  -webkit-animation-direction: alternate;
  animation-direction: alternate;
}

@-moz-keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}

@-webkit-keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}

@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}
```

#### 애니메이션 이벤트 리스너 추가하기

JavaScript 코드를 사용하여 위에서 언급한 세개의 이벤트를 감지해 봅시다. `setup()` 함수는 애니메이션 이벤트 리스너를 추가하는 함수입니다. 문서가 로드되었을 때 이 함수를 실행할 것입니다.

```js
function setup() {
  var e = document.getElementById("watchme");
  e.addEventListener("animationstart", listener, false);
  e.addEventListener("animationend", listener, false);
  e.addEventListener("animationiteration", listener, false);

  var e = document.getElementById("watchme");
  e.className = "slidein";
}
```

어떻게 동작하는지 더 자세히 알고싶으면 `element.addEventListener()` 문서를 참고하세요. setup() 함수의 마지막 줄에서 엘리먼트의 `class` 를 "slidein"으로 지정하는 순간 애니메이션이 시작됩니다.

왜 이렇게 했을까요? 왜냐하면 `animationstart` 이벤트는 애니메이션이 시작되자마자 발생하므로 우리 코드에서는 이를 감지할 수 없습니다. 애니메이션이 시작될 때는 위의 코드가 실행되기 전이라 이벤트 리스너가 아직 추가되지 않았기 때문이지요. 따라서 이벤트 리스너를 먼저 추가하고 엘리먼트에 class를 지정하여 애니메이션을 시작했습니다.

#### 이벤트 받기

각 이벤트가 발생할 때마다 `listener()` 함수로 넘겨집니다. 이 함수의 코드는 아래와 같습니다.

```js
function listener(e) {
  var l = document.createElement("li");
  switch (e.type) {
    case "animationstart":
      l.innerHTML = "Started: elapsed time is " + e.elapsedTime;
      break;
    case "animationend":
      l.innerHTML = "Ended: elapsed time is " + e.elapsedTime;
      break;
    case "animationiteration":
      l.innerHTML = "New loop started at time " + e.elapsedTime;
      break;
  }
  document.getElementById("output").appendChild(l);
}
```

이 코드 역시 굉장히 단순합니다. `event.type` 을 보고 어떤 이벤트가 발생했는지 확인합니다. 그리고 `<ul>` (순서 없는 리스트)에 그 이벤트의 로그를 나타내는 엘리먼트를 추가합니다.

결과는 다음과 같습니다.

* Started: elapsed time is 0
* New loop started at time 3.01200008392334
* New loop started at time 6.00600004196167
* Ended: elapsed time is 9.234000205993652

이벤트가 발생한 시각이 위에서 지정한 애니메이션 시간과 굉장히 가깝지만 정확히 같지는 않다는걸 기억하세요. 또 애니메이션의 반복이 끝나는 순간에는 `animationiteration` 이벤트가 발생하지 않고 `animationend` 이벤트가 발생했다는걸 기억하세요.

#### HTML 코드

완벽을 위해 예제에서 사용한 HTML 코드도 첨부합니다. 여기에는 페이지 내용뿐만 아니라 이벤트 로깅을 위한 ul 엘리먼트도 있습니다.

```html
<body onload="setup()">
  <h1 id="watchme">Watch me move</h1>
  <p>
    This example shows how to use CSS animations to make
    <code>h1</code> elements move across the page.
  </p>
  <p>
    In addition, we output some text each time an animation event fires, so you
    can see them in action.
  </p>
  <ul id="output"></ul>
</body>
```

더 보기
----

* `AnimationEvent`
* Detecting CSS animation support


CSS 변형 사용하기 - CSS: Cascading Style Sheets

CSS 변형 사용하기
===========

**CSS 변형**(transform)은 좌표공간을 변형함으로써 일반적인 문서 흐름을 방해하지 않고 콘텐츠의 형태와 위치를 바꿉니다. 본 가이드는 변형 사용법의 기초를 제시합니다.

CSS 변형은 HTML 요소에 선형 아핀 변형(affine linear transformation)을 적용하는 여러 개의 CSS 속성을 조합해 구현합니다. 변형은 평면과 3D 공간에서의 회전, 확대, 이동, 비틀기를 포함합니다.

**경고:** 박스 모델에 따라 배치된 요소만 `transform`을 적용할 수 있습니다. 한 가지 예를 들자면, `display: block` 속성을 가진 요소는 박스 모델을 따릅니다.

CSS 변형 속성
---------

CSS 변형을 정의할 때 중요한 두 가지 속성은 `transform`과 `transform-origin` (en-US)입니다.

`transform-origin` (en-US)

원점의 위치를 지정합니다. 기본값은 요소의 중심이며 변경할 수 있습니다. 회전, 확대, 비틀기 등 하나의 점을 기준으로 하는 변형에서 사용합니다.

`transform`

요소에 적용할 변형을 지정합니다. 여러 개의 변형 목록을 공백으로 구분하여 대입하면 순차적으로 합성한 결과물을 적용합니다. 합성은 오른쪽부터 왼쪽으로 진행합니다.

예제
--

다음 이미지는 변형하지 않은 MDN 로고입니다.

![MDN Logo](/ko/docs/Web/CSS/CSS_transforms/Using_CSS_transforms/logo.png)

### 회전

MDN 로고를 90도 회전합니다.

```html
<img
 style="transform: rotate(90deg);
 transform-origin: bottom left;"
 src="logo.png" />
```

### 비틀고 옮기기

MDN 로고를 10도 비틀고 X축으로 150픽셀 옮깁니다.

```html
<img
 style="transform: skewx(10deg) translatex(150px);
 transform-origin: bottom left;"
 src="logo.png" />
```

3D 전용 CSS 속성
------------

3D 공간에서의 CSS 변환은 좀 더 복잡합니다. 우선 원근감을 부여해 3D 공간을 설정한 후에, 2D 요소가 그 안에서 어떻게 행동할지 설정해야 합니다..

### 원근

처음으로 정할 항목은 `perspective` (en-US)입니다. 우리가 입체라고 느낄 수 있는 건 원근감 덕분입니다. 요소가 관찰자에서 멀어질 수록 더 작게 보입니다.

#### Setting perspective

This example shows a cube with the perspective set at different positions. How quick the cube shrinks is defined by the `perspective` (en-US) property. The smaller its value is, the deeper the perspective is.

##### HTML

The HTML below creates four copies of the same box, with the perspective set at different values.

```html
<table>
  <tbody>
    <tr>
      <th><code>perspective: 250px;</code></th>
      <th><code>perspective: 350px;</code></th>
    </tr>
    <tr>
      <td>
        <div class="container">
          <div class="cube pers250">
            <div class="face front">1</div>
            <div class="face back">2</div>
            <div class="face right">3</div>
            <div class="face left">4</div>
            <div class="face top">5</div>
            <div class="face bottom">6</div>
          </div>
        </div>
      </td>
      <td>
        <div class="container">
          <div class="cube pers350">
            <div class="face front">1</div>
            <div class="face back">2</div>
            <div class="face right">3</div>
            <div class="face left">4</div>
            <div class="face top">5</div>
            <div class="face bottom">6</div>
          </div>
        </div>
      </td>
    </tr>
    <tr>
      <th><code>perspective: 500px;</code></th>
      <th><code>perspective: 650px;</code></th>
    </tr>
    <tr>
      <td>
        <div class="container">
          <div class="cube pers500">
            <div class="face front">1</div>
            <div class="face back">2</div>
            <div class="face right">3</div>
            <div class="face left">4</div>
            <div class="face top">5</div>
            <div class="face bottom">6</div>
          </div>
        </div>
      </td>
      <td>
        <div class="container">
          <div class="cube pers650">
            <div class="face front">1</div>
            <div class="face back">2</div>
            <div class="face right">3</div>
            <div class="face left">4</div>
            <div class="face top">5</div>
            <div class="face bottom">6</div>
          </div>
        </div>
      </td>
    </tr>
  </tbody>
</table>
```

##### CSS

The CSS establishes classes that can be used to set the perspective to different distances. It also includes classes for the container box and the cube itself, as well as each of its faces.

```css
/\* Shorthand classes for different perspective values \*/
.pers250 {
  perspective: 250px;
}

.pers350 {
  perspective: 350px;
}

.pers500 {
  perspective: 500px;
}

.pers650 {
  perspective: 650px;
}

/\* Define the container div, the cube div, and a generic face \*/
.container {
  width: 200px;
  height: 200px;
  margin: 75px 0 0 75px;
  border: none;
}

.cube {
  width: 100%;
  height: 100%;
  backface-visibility: visible;
  perspective-origin: 150% 150%;
  transform-style: preserve-3d;
}

.face {
  display: block;
  position: absolute;
  width: 100px;
  height: 100px;
  border: none;
  line-height: 100px;
  font-family: sans-serif;
  font-size: 60px;
  color: white;
  text-align: center;
}

/\* Define each face based on direction \*/
.front {
  background: rgba(0, 0, 0, 0.3);
  transform: translateZ(50px);
}

.back {
  background: rgba(0, 255, 0, 1);
  color: black;
  transform: rotateY(180deg) translateZ(50px);
}

.right {
  background: rgba(196, 0, 0, 0.7);
  transform: rotateY(90deg) translateZ(50px);
}

.left {
  background: rgba(0, 0, 196, 0.7);
  transform: rotateY(-90deg) translateZ(50px);
}

.top {
  background: rgba(196, 196, 0, 0.7);
  transform: rotateX(90deg) translateZ(50px);
}

.bottom {
  background: rgba(196, 0, 196, 0.7);
  transform: rotateX(-90deg) translateZ(50px);
}

/\* Make the table a little nicer \*/
th,
p,
td {
  background-color: #eeeeee;
  padding: 10px;
  font-family: sans-serif;
  text-align: left;
}
```

##### Result

다음으로는 `perspective-origin` (en-US) 속성으로 관찰자의 위치를 정해야 합니다. 기본값은 중앙으로, 언제나 충분한 위치는 아닙니다.

#### Changing the perspective origin

This example shows cubes with popular `perspective-origin` values.

##### HTML

```html
<section>
  <figure>
    <figcaption><code>perspective-origin: top left;</code></figcaption>
    <div class="container">
      <div class="cube potl">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: top;</code></figcaption>
    <div class="container">
      <div class="cube potm">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: top right;</code></figcaption>
    <div class="container">
      <div class="cube potr">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: left;</code></figcaption>
    <div class="container">
      <div class="cube poml">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: 50% 50%;</code></figcaption>
    <div class="container">
      <div class="cube pomm">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: right;</code></figcaption>
    <div class="container">
      <div class="cube pomr">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: bottom left;</code></figcaption>
    <div class="container">
      <div class="cube pobl">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: bottom;</code></figcaption>
    <div class="container">
      <div class="cube pobm">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: bottom right;</code></figcaption>
    <div class="container">
      <div class="cube pobr">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: -200% -200%;</code></figcaption>
    <div class="container">
      <div class="cube po200200neg">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: 200% 200%;</code></figcaption>
    <div class="container">
      <div class="cube po200200pos">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>

  <figure>
    <figcaption><code>perspective-origin: 200% -200%;</code></figcaption>
    <div class="container">
      <div class="cube po200200">
        <div class="face front">1</div>
        <div class="face back">2</div>
        <div class="face right">3</div>
        <div class="face left">4</div>
        <div class="face top">5</div>
        <div class="face bottom">6</div>
      </div>
    </div>
  </figure>
</section>
```

##### CSS

```css
/\* perspective-origin values (unique per example) \*/
.potl {
  perspective-origin: top left;
}
.potm {
  perspective-origin: top;
}
.potr {
  perspective-origin: top right;
}
.poml {
  perspective-origin: left;
}
.pomm {
  perspective-origin: 50% 50%;
}
.pomr {
  perspective-origin: right;
}
.pobl {
  perspective-origin: bottom left;
}
.pobm {
  perspective-origin: bottom;
}
.pobr {
  perspective-origin: bottom right;
}
.po200200neg {
  perspective-origin: -200% -200%;
}
.po200200pos {
  perspective-origin: 200% 200%;
}
.po200200 {
  perspective-origin: 200% -200%;
}

/\* Define the container div, the cube div, and a generic face \*/
.container {
  width: 100px;
  height: 100px;
  margin: 24px;
  border: none;
}

.cube {
  width: 100%;
  height: 100%;
  backface-visibility: visible;
  perspective: 300px;
  transform-style: preserve-3d;
}

.face {
  display: block;
  position: absolute;
  width: 100px;
  height: 100px;
  border: none;
  line-height: 100px;
  font-family: sans-serif;
  font-size: 60px;
  color: white;
  text-align: center;
}

/\* Define each face based on direction \*/
.front {
  background: rgba(0, 0, 0, 0.3);
  transform: translateZ(50px);
}
.back {
  background: rgba(0, 255, 0, 1);
  color: black;
  transform: rotateY(180deg) translateZ(50px);
}
.right {
  background: rgba(196, 0, 0, 0.7);
  transform: rotateY(90deg) translateZ(50px);
}
.left {
  background: rgba(0, 0, 196, 0.7);
  transform: rotateY(-90deg) translateZ(50px);
}
.top {
  background: rgba(196, 196, 0, 0.7);
  transform: rotateX(90deg) translateZ(50px);
}
.bottom {
  background: rgba(196, 0, 196, 0.7);
  transform: rotateX(-90deg) translateZ(50px);
}

/\* Make the layout a little nicer \*/
section {
  background-color: #eee;
  padding: 10px;
  font-family: sans-serif;
  text-align: left;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
```

##### Result

모든 과정을 마쳤다면 3D 공간의 요소를 작업할 수 있습니다.

더 보기
----

* Using device orientation with 3D Transforms (en-US)