번역 작업 진행중입니다.

일반적으로 flexbox라 불리는 Flexible Box 모듈은 1차원 레이아웃 모델로서 설계되었습니다. Flexbox의 강력한 정렬 기능으로 인터페이스 요소 사이의 공간 배분을 조정할 수 있습니다. 이 글에서는 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.

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

If flex-direction is set to column the main axis runs in the block direction.

교차축

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

If flex-direction is set to row then the cross axis runs in the block direction.

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

If flex-direction is set to column then the cross axis runs in the inline direction.

flex 요소를 정렬하고 정의하려면  어느 축이 어느 방향인지 이해하는 것이 중요합니다. flexbox feature property들은 주축, 교차축을 따라 항목을 정렬하고 정의합니다.

시작선과 끝선

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

이어지는 다른 글에서 flexbox와 쓰기 방법의 설계가 어떤 관련이 있는지 알아볼 수 있습니다. 그 전에, flex 요소의 정렬 방향에 "왼쪽, 오른쪽, 위, 아래"를  사용하지 않는지 설명하겠습니다.

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

Working in English the start edge is on the left.

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

The start edge in a RTL language is on the right.

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

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

flex 컨테이너

문서의 영역 중에서 flexbox가 놓여있는 영역을 flex 컨테이너라고 부릅니다. flex 컨테이너를 생성하려면 영역 내의 컨테이너 요소의 display 값을 flex 혹은 inline-flex로 설정합니다. 이 값이 설정된 컨테이너의 자식 요소는 flex 항목이 됩니다. 다른 CSS속성과 마찬가지로 일부의 값은 초깃값이 지정됩니다. 따라서 flex 컨테이너를 생성할 때 포함된 모든 flex 항목은 다음과 같이 동작합니다.

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

결과적으로 항목은 내부 요소의 크기가 주축 상에서 가지는 값을 크기로 가지며 행을 따라서 나열됩니다. 컨테이너의 크기보다 더 많은 항목이 있을 경우 행을 바꾸지 않고 흘러 넘치게 됩니다. 어떤 항목이 다른 항목보다 높이 값이 크다면 나머지 모든 항목들은 그에 맞게 교차축을 따라 늘어나게 됩니다.

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

 

flex-direction 바꾸기

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

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

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

여러 행을 가진 flex 컨테이너

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

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

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

축약 속성 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 항목에 적용할 수 있는 속성은 다음과 같습니다.

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

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

This flex container has available space after laying out the items.

앞서 언급한 세 가지 속성을 변경한다는 것은 flex 요소에게 사용가능한 공간을 분배하는 방식을 변경하는 것입니다. 사용가능한 공간 개념은 flex 요소를 정렬할 때 특히 중요합니다.

flex-basis 속성

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

flex 항목이 크기를 갖지 않는다면 내용물의 크기가 flex-basis 값으로 사용됩니다. 따라서 컨테이너에서 display: flex 속성을 설정하면 자식 요소들이 각자 내용물의 크기만큼만 공간을 차지하게 됩니다.

flex-grow 속성

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


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

flex-shrink 속성

flex-grow 속성이 주축에서 남는 공간을 항목들에게 분배하는 방법을 결정한다면 flex-shrink 속성은 주축의 공간이 부족할때 각 항목의 사이즈를 줄이는 방법을 정의합니다.

만약 flex 컨테이너가 자식 요소를 모두 포함할만큼 넉넉한 공간을 갖고 있지 않으면 설정된 flex-shrink 값에 따라서 항목의 사이즈가 줄어들게 됩니다. flex-grow 속성과 마찬가지로 더 큰 flex-shrink 값을 갖는 항목의 사이즈가 더 많이 줄어듭니다.


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

Note that these values for flex-grow and flex-shrink are proportions. Typically if we had all of our items set to flex: 1 1 200px and then wanted one item to grow at twice the rate, we would set that item to flex: 2 1 200px. However you could use flex: 10 1 200px and flex: 20 1 200px if you wanted.

Shorthand values for the flex properties

You will very rarely see the flex-grow, flex-shrink, and flex-basis properties used individually; instead they are combined into the flex shorthand. The flex shorthand allows you to set the three values in this order — flex-grow, flex-shrink, flex-basis.

The live example below allows you to test out the different values of the flex shorthand; remember that the first value is flex-grow. Giving this a positive value means the item can grow. The second is flex-shrink — with a positive value the items can shrink, but only if their total values overflow the main axis. The final value is flex-basis; this is the value the items are using as their base value to grow and shrink from.

There are also some predefined shorthand values which cover most of the use cases. You will often see these used in tutorials, and in many cases these are all you will need to use. The predefined values are as follows:

  • flex: initial
  • flex: auto
  • flex: none
  • flex: <positive-number>

Setting flex: initial resets the item to the initial values of Flexbox. This is the same as flex: 0 1 auto. In this case the value of flex-grow is 0, so items will not grow larger than their flex-basis size. The value of flex-shrink is 1, so items can shrink if they need to rather than overflowing. The value of flex-basis is auto. Items will either use any size set on the item in the main dimension, or they will get their size from the content size.

Using flex: auto is the same as using flex: 1 1 auto; everything is as with flex:initial but in this case the items can grow and fill the container as well as shrink if required.

Using flex: none will create fully inflexible flex items. It is as if you wrote flex: 0 0 auto. The items cannot grow or shrink but will be laid out using flexbox with a flex-basis of auto.

The shorthand you often see in tutorials is flex: 1 or flex: 2 and so on. This is as if you used flex: 1 1 0. The items can grow and shrink from a flex-basis of 0.

Try these shorthand values in the live example below.

Alignment, justification and distribution of free space between items

A key feature of flexbox is the ability to align and justify items on the main- and cross-axes, and to distribute space between flex items.

align-items

The align-items property will align the items on the cross axis.

The initial value for this property is stretch and this is why flex items stretch to the height of the tallest one by default. They are in fact stretching to fill the flex container — the tallest item is defining the height of that.

You could instead set align-items to flex-start in order to make the items line up at the start of the flex container, flex-end to align them to the end, or center to align them in the centre. Try this in the live example — I have given the flex container a height in order that you can see how the items can be moved around inside the container. See what happens if you set the value of align-items to:

  • stretch
  • flex-start
  • flex-end
  • center

justify-content

The justify-content property is used to align the items on the main axis, the direction in which flex-direction has set the flow. The initial value is flex-start which will line the items up at the start edge of the container, but you could also set the value to flex-end to line them up at the end, or center to line them up in the centre.

You can also use the value space-between to take all the spare space after the items have been laid out, and share it out evenly between the items so there will be an equal amount of space between each item. To cause an equal amount of space on the right and left of each item use the value space-around. With space-around, items have a half-size space on either end. Or, to cause items to have equal space around them use the value space-evenly. With space-evenly, items have a full-size space on either end.

Try the following values of justify-content in the live example:

  • stretch
  • flex-start
  • flex-end
  • center
  • space-around
  • space-between
  • space-evenly

In the article Aligning Items in a Flex Container we will explore these properties in more depth, in order to have a better understanding of how they work. These simple examples however will be useful in the majority of use cases.

Next steps

After reading this article you should have an understanding of the basic features of Flexbox. In the next article we will look at how this specification relates to other parts of CSS.

문서 태그 및 공헌자

이 페이지의 공헌자: silmari, soonoo, wankyu, Latera
최종 변경: silmari,