플렉스박스
CSS 3에서 추가된 플렉스박스(flexbox), 플렉서블 박스 레이아웃(flexible box layout)은 플렉스 컨테이너와 그 하위 요소인 플렉스 요소(들)을 활용해 요소를 배치하고 레이아웃을 구성할 수 있게 해준다.
플렉스 박스를 사용하려면 플렉스 컨테이너가 될 요소의 스타일에 display: flex
혹은 display: inline-flex
를 추가한다. 값을 flex
로 추가하면 플렉스 컨테이너는 블록 요소가 되어 한 줄을 모두 차지하고, inline-flex
로 값을 설정하면 플렉스 컨테이너는 인라인 요소가 되어 한 줄에서 필요한 만큼만 공간을 차지한다.
.container {
display: flex;
}
<!-- 플렉스 컨테이너 -->
<div class="container">
<div>플렉스 요소</div>
<div>플렉스 요소</div>
</div>
플렉스 요소의 크기
플렉스 요소들의 너비는 플렉스 컨테이너의 너비 안에서 비율에 따라 조정될 수 있는데, flex-shrink
, flex-grow
, flex-basis
속성이나 flex
속성을 사용한다.
만약 플렉스 요소들의 너비가 플렉스 컨테이너의 정해진 너비보다 커지면 플렉스 요소의 너비는 플렉스 컨테이너의 크기를 따라 줄어든다. flex-shrink
의 기본값은 1로 설정되어 있다. 반면 플렉스 요소들의 너비가 정해진 플렉스 컨테이너의 너비보다 작은 경우 플렉스 요소의 너비는 플렉스 컨테이너를 따라 늘어나지 않는다. flex-grow
의 기본값은 0으로 설정되어 있다.
.container {
display: flex;
}
.side {
flex-shrink: 1;
flex-grow: 1;
}
.center {
flex-shrink: 3;
flex-grow: 3;
}
<div class="container">
<div class="side"></div>
<div class="center"></div>
<div class="side"></div>
</div>
위 예에서 화면의 가로 길이가 변경되어 플렉스 컨테이너의 너비가 변경될 경우 .side
의 너비는 플렉스 컨테이너 너비의 20%로, .center
의 너비는 플렉스 컨테이너 너비의 60%로 줄어들거나 늘어난다.
플렉스 요소의 너비에 변화가 생기기 전의 기본 너비는 flex-basis
속성으로 정할 수 있다. 다른 변화가 없다면 플렉스 요소는 flex-basis
의 너비를 사용하고, 변화가 생기는 경우 플렉스 요소의 너비는 flex-grow
나 flex-shrink
수치를 따라 변화한다. flex-basis
의 값이 0일 경우에는 flex-grow
나 flex-shrink
의 값을 따르고 값이 flex-basis
의 값이 auto
일 경우에는 플렉스 요소의 너비를 값으로 사용한다.
flex-grow
, flex-shrink
, flex-basis
속성은 다음과 같이 flex
속성으로 묶어서 코드를 쓸 수 있다.
.side {
flex-shrink: 1;
flex-grow: 2;
flex-basis: 150px;
}
.side {
flex: 2 1 150px;
}
flex
속성의 값은 flex-grow
, flex-shrink
, flex-basis
순서로 쓰고, 세 값 대신 auto
나 initial
, none
을 값으로 쓸 수도 있다. auto
를 쓰면 플렉스 요소의 너비는 요소의 width
를 따르며 플렉스 컨테이너의 너비가 변경되면 그에 따라 늘어나거나 줄어든다(flex: 1 1 auto
와 같다). initial
값이라면 플렉스 요소의 너비는 요소의 width
를 따르며 플렉스 컨테이너의 너비가 줄어들 경우 플렉스 요소도 그에 맞춰 줄어들지만 플렉스 컨테이버의 너비가 늘어날 경우 정해진 크기보다 더 늘어나지는 않는다(속성의 기본값인 flex: 0 1 auto
와 같다). none
을 값으로 사용하면 플렉스 요소들의 너비는 플렉스 컨테이너의 너비와 무관하게 된다(flex: 0 0 auto
와 같다).
플렉스 요소의 배치
기본적으로 플렉스 요소들은 플렉스 컨테이너 안에서 한 줄로 배치되는데, 플렉스 요소들이 플렉스 컨테이너의 크기를 변하게 하지 않고 플렉스 컨테이너의 너비 안에서 너비 제한을 넘으려 하는 플렉스 요소를 다음 줄로 보내게 할 수도 있다. 이때 플렉스 컨테이너에 flex-wrap
속성을 사용한다.
flex-wrap
의 값으로는 다음 세 가지를 사용할 수 있다.
wrap
: 너비 제한을 넘으려는 플렉스 요소를 다음 행으로 이동시킨다.wrap-reverse
:wrap
을 행의 순서를 반대로 바꿔 실행한다.nowrap
: 속성의 기본값으로, 플렉스 요소를 다음 행으로 보내지 못하게 한다.
기본적으로 플렉스 요소들은 왼쪽에서 오른쪽으로 배치된다. 이 방향을 수정하려면 플렉스 컨테이너에 flex-direction
속성을 사용한다.
flex-direction
의 값으로는 다음 네 가지를 사용할 수 있다.
row
: 속성의 기본값으로, 플렉스 요소들이 선언된 순서에 따라 왼쪽에서 오른쪽으로 배치된다.row-inverse
: 플렉스 요소들이 선언된 순서에 따라 오른쪽에서 왼쪽으로 배치된다.column
: 플렉스 요소들이 선언된 순서에 따라 위에서 아래로 배치된다.column-inverse
: 플렉스 요소들이 선언된 순서에 따라 아래에서 위로 배치된다.
flex-direction
과 flex-wrap
은 flex-flow
속성으로 묶어서 코드를 작성할 수 있다. 플렉스 요소들을 왼쪽에서 오른쪽으로 배치하고(flex-direction: row
) 플렉스 컨테이너의 너비를 넘으려 하는 요소들을 다음 줄로 보내고(flex-wrap: wrap
) 싶다면 flex-flow
속성을 플렉스 컨테이너에 적용시킨다.
flex-flow: row wrap;
플렉스 요소의 정렬
플렉스 컨테이너에 justify-content
속성을 적용하면 기본적으로 왼쪽에 수평 정렬되는 플렉스 요소들을 가운데 정렬하거나 오른쪽 정렬할 수 있다.
flex-start
: 플렉스 컨테이너의 왼쪽 끝에서부터 플렉스 요소들이 배치된다.flex-end
: 플렉스 컨테이너의 오른쪽 끝에서부터 플렉스 요소들이 배치된다.center
: 배치된 플렉스 요소들이 플렉스 컨테이너의 가운데에 정렬된다.space-between
: 첫 플렉스 요소는 플렉스 컨테이너의 왼쪽 끝에 배치되고 마지막 플렉스 요소는 오른쪽 끝에 배치된다. 나머지 요소들은 그 사이에 같은 간격으로 배치된다.space-around
: 모든 플렉스 요소들이 같은 간격으로 배치된다.
플렉스 요소들을 수직 정렬하려면 플렉스 컨테이너에 align-items
속성을 사용한다.
stretch
: 플렉스 요소들이 플렉스 요소들이 세로 축을 꽉 채우게 된다.flex-start
: 플렉스 요소들이 플렉스 컨테이너의 위쪽 끝에서부터 배치된다.flex-end
: 플렉스 요소들이 플렉스 컨테이너의 아래쪽 끝에서부터 배치된다.center
: 플렉스 요소들이 플렉스 컨테이너의 가운데에 수직 정렬된다.baseline
: 플렉스 요소들이 플렉스 컨테이너의 위쪽 끝으로부터 가장 먼 글자 기준선(baseline)을 따라 정렬된다. MDN에서 예제를 볼 수 있다.
플렉스 요소 중 어느 한 요소에만 수직 정렬을 적용하고 싶다면 align-self
속성을 해당 플렉스 요소에 적용한다. align-items
의 값을 동일하게 사용할 수 있으며 여기에 상위 요소의 값을 상속받는 auto
값을 추가로 사용할 수 있다.
플렉스 요소들이 여러 행에 걸쳐 표시될 때는 align-content
속성을 사용할 수 있다.
flex-start
: 플렉스 요소들이 플렉스 컨테이너의 위쪽 끝에서부터 배치된다.flex-end
: 플렉스 요소들이 플렉스 컨테이너의 아래쪽 끝에서부터 배치된다.center
: 플렉스 요소들이 플렉스 컨테이너의 가운데에 수직 정렬된다.space-between
: 첫 행의 플렉스 요소들은 플렉스 컨테이너의 위쪽 끝에 배치되고 마지막 행의 플렉스 요소들은 아래쪽 끝에 배치된다. 나머지 요소들은 그 사이에 같은 간격으로 배치된다.space-around
: 모든 플렉스 요소들이 같은 간격으로 배치된다.