Flexbox는 모던 웹을 위하여 제안된, 기존 레이아웃보다 더 세련된 방식의 CSS3의 새로운 레이아웃 방식이다.
element의 사이즈가 불명확하거나 동적으로 변화할 때에도 유연한 레이아웃을 실현할 수 있다. 또, 복잡한 레이아웃이라도 적은 코드로 보다 간단하게 표현할 수 있다.
이해를 돕기 위해 간단한 flexbox 레이아웃을 만들어 보자.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Flexbox Layout Example</title>
<style>
.flex-container {
margin: 10px;
padding: 15px;
border-radius: 5px;
background: #60B99A;
}
.flex-item {
margin: 10px;
padding: 20px;
color: #fff;
text-align: center;
border-radius: 5px;
background: #4584b1;
}
</style>
</head>
<body>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
</div>
</body>
</html>
<div>
element는 block level element이므로 수직 정렬된다. 이를 수평 정렬하려면 자식 element를 inline-block으로 지정하거나 float
property를 지정한다.
.flex-item {
display: inline-block;
/* or */
float: left;
}
이 때 각 자식 element를 부모 element 내에서 균일하게 정렬하기 위해서는 각 자식 element의 너비를 %로 지정하는 등 번거로운 처리가 필요하다. 자식 element의 사이즈가 불명확하거나 동적으로 변화할 때에는 더욱 처리가 복잡해진다. grid 시스템을 사용할 수도 있으나 라이브러리를 로드해야하는 등의 번거로움이 존재한다.
Flexbox를 사용하여 위 예제를 부모 element 내에서 균등하게 수평 정렬해보자. 부모 element에 아래와 같이 코드 두 줄을 추가하면 된다.
.flex-container {
display: flex;
justify-content: space-around;
}
이처럼 Flexbox를 사용하면 기존 방식에 비해 매우 간단히 레이아웃을 처리할 수 있다.
Flexbox의 장점을 정리해보면 아래와 같다.
비교적 최신 브라우저가 아니면 vendor prefix를 사용해야한다.
Flexbox 레이아웃은 flex item이라 불리는 다수의 자식 element와 이들을 포함하는 flex-container라 불리는 부모 element로 구성된다.
flexbox를 사용하기 위해서 부모 element의 display
property에 flex를 지정한다. 만약, 부모 element가 inline element인 경우 inline-flex를 지정한다.
.flex-container {
display: flex;
}
/* if element is inline */
.flex-container {
display: inline-flex
}
flex 또는 inline-flex는 부모 element에 반드시 지정해야하는 유일한 속성이며, 자식 element는 자동적으로 flex item이 된다.
flex container의 주축(main axis) 방향을 설정한다.
property value에 따라 다음과 같다.
row
: 좌에서 우로 수평 배치된다. 기본값.flex-container {
flex-direction: row;
}
row-reverse
: 우에서 좌로 수평 배치된다..flex-container {
flex-direction: row-reverse;
}
column
: 위에서 아래로 수직 배치된다..flex-container {
flex-direction: column;
}
column-reverse
: 아래에서 위로 수직 배치된다..flex-container {
flex-direction: column-reverse;
}
flex container의 여러 개의 flex item을 1행 또는 복수행으로 배치한다.
property value에 따라 다음과 같다.
nowrap
: flex item을 개행하지 않고, 1행에 배치한다. 각 flex item의 너비는 flex container에 들어갈 수 있는 크기로 축소된다. 기본값..flex-container {
flex-wrap: nowrap;
}
<!DOCTYPE html>
<html>
<head>
<title>Flexbox</title>
<meta charset="UTF-8">
<style>
.flex-container {
width: 500px;
margin: 10px;
padding: 15px;
border-radius: 5px;
background: #60B99A;
display: flex;
flex-wrap: nowrap;
}
.flex-item {
margin: 10px;
padding: 20px;
color: #fff;
text-align: center;
border-radius: 5px;
background: #4584b1;
}
</style>
</head>
<body>
<div class="flex-container">
<div class="flex-item">11111</div>
<div class="flex-item">22222</div>
<div class="flex-item">33333</div>
<div class="flex-item">44444</div>
<div class="flex-item">55555</div>
</div>
</body>
</html>
하지만 flex item들의 width의 합계가 flex container의 width보다 큰 경우에 flex container를 넘치게 된다. 이 때 overflow: auto;
를 지정하면 가로 스크롤이 생기며 container를 넘치지 않는다.
<!DOCTYPE html>
<html>
<head>
<title>Flexbox</title>
<meta charset="UTF-8">
<style>
.flex-container {
width: 500px;
margin: 10px;
padding: 15px;
border-radius: 5px;
background: #60B99A;
display: flex;
flex-wrap: nowrap;
overflow: auto;
}
.flex-item {
margin: 10px;
padding: 20px;
color: #fff;
text-align: center;
border-radius: 5px;
background: #4584b1;
}
</style>
</head>
<body>
<div class="flex-container">
<div class="flex-item">11111111</div>
<div class="flex-item">22222222</div>
<div class="flex-item">33333333</div>
<div class="flex-item">44444444</div>
<div class="flex-item">55555555</div>
</div>
</body>
</html>
wrap
: flex item들의 width 합계가 flex container의 width보다 큰 경우, flex item들을 여러 행에 배치한다. 기본적으로 좌에서 우로, 위에서 아래로 배치된다..flex-container {
flex-wrap: wrap;
}
wrap-reverse;
: wrap과 동일하나, 아래에서 위로 배치된다..flex-container {
flex-wrap: wrap-reverse;
}
flex-direction
과 flex-wrap
을 한 번에 설정할 수 있다. 기본값은 row nowrap
이다.
.flex-container {
flex-flow: <flex-direction> <flex-wrap>;
}
flex container의 main axis를 기준으로 flex item을 수평 정렬한다.
property value에 따라 다음과 같다.
flex-start
: main start(좌측)을 기준으로 정렬한다. 기본값..flex-container {
justify-content: flex-start;
}
flex-end
: main end(우측)을 기준으로 정렬한다..flex-container {
justify-content: flex-end;
}
center
: flex container의 중앙에 정렬한다..flex-container {
justify-content: center;
}
space-between
: 첫 번째와 마지막 flex item은 좌우 측면에 정렬되고, 나머지는 균등한 간격으로 정렬된다..flex-container {
justify-content: space-between;
}
space-around
: 모든 flex item은 균등한 간격으로 정렬된다..flex-container {
justify-content: space-around;
}
flex item을 flex container의 수직 방향(cross axis)으로 정렬한다.
property value에 따라 다음과 같다.
stretch
: 모든 flex item은 flex container의 높이(cross start에서 cross end까지의 높아)에 꽉 찬 높이를 갖는다. 기본값.flex-container {
align-items: stretch;
}
flex-start
: 모든 flex item은 flex container의 cross start 기준으로 정렬된다..flex-container {
align-items: flex-start;
}
flex-end
: 모든 flex item은 flex container의 cross end 기준으로 정렬된다..flex-container {
align-items: flex-end;
}
center
: 모든 flex item은 flex container의 cross axis의 중앙에 정렬된다..flex-container {
align-items: center;
}
baseline
: 모든 flex item은 flex container의 baseline을 기준으로 정렬된다..flex-container {
align-items: baseline;
}
flex container의 cross axis를 기준으로 flex item을 수직 정렬한다.
property value에 따라 다음과 같다.
stretch
: 모든 flex item은 균등하게 분배된 공간에 정렬되어 배치된다. 기본값..flex-container {
align-content: stretch;
}
flex-start
: 모든 flex item은 flex container의 cross start 기준으로 stack 정렬된다..flex-container {
align-content: flex-start;
}
flex-end
: 모든 flex item은 flex container의 cross end 기준으로 stack 정렬된다..flex-container {
align-content: flex-end;
}
center
: 모든 flex item은 flex container의 cross axis의 중앙에 stack 정렬된다..flex-container {
align-content: center;
}
space-between
: 첫 번째 flex item 행은 flex container의 상단에 마지막 flex item의 행은 flex container의 하단에 배치되며 나머지 행은 균등하게 분할된 공간에 정렬 배치된다..flex-container {
align-content: space-between;
}
space-around
: 모든 flex item은 균등하게 분할된 공간 내에 배치 정렬된다..flex-container {
align-content: space-around;
}
float
, clear
, vertical-align
property는 flex item에 영향을 주지 않는다.
flex item의 배치 순서를 지정한다. HTML 코드를 변경하지 않고, order property에 값을 지정하는 것으로 간단히 재배치할 수 있다.
기본 배치 순서는 flex container에 추가된 순서이고, 값이 클 수록 뒤에 배치된다. 기본값은 0이다.
.flex-item {
order: 정수값;
}
flex item의 너비에 대한 확대 인자를 지정한다.
기본값은 0이고, 음수값은 무효하다.
.flex-item {
flex-grow: 양의 정수값;
}
모든 flex item이 동일한 값을 가지면 모든 flex item은 동일한 너비를 갖는다.
값이 클 수록 다른 flex item보다 더 넓은 너비를 갖는다.
flex item의 너비에 대한 축소 인자를 지정한다.
기본값은 1로 모든 flex item이 축소된 상태로 지정되고, 음수값은 무효하다.
.flex-item {
flex-shrink: 양의 정수값;
}
0을 지정하면 축소가 해제되어 원래의 너비를 유지한다.
flex item의 너비 기본값을 px, %, 등의 단위로 지정한다.
기본값은 auto이다.
.flex-item {
flex-basis: auto;
}
flex-grow
, flex-shrink
, flex-basis
property들을 한 번에 지정할 수 있다.
기본값은 0 1 auto이다.
W3C에서는 이 property보다는 개별적으로 기술하는 것을 추천한다.
.flex-item {
flex: none | auto | [ <flex-grow> <flex-shrink>? || <flex-basis> ];
}
align-items
property보다 우선하여 개별 flex item을 정렬한다.
기본값은 auto이다.
.flex-item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}