Flex
Flex는 Flexible Box라고 불릴 만큼 유연한 레이아웃을 표현할 수 있다.
또한 Grid와 더불어 대표적인 차세대 CSS 레이아웃으로 알려져 있다.
Grid는 Flex보다 더 최신 문법이고 Flex 레이아웃이 대부분 Grid로도 구현할 수 있긴 하다.
그렇다고 Flex를 배울 필요가 없는 것은 아니다. 설계 목적이 다르기 때문이다.
- Flex: 1차원 레이아웃
- Grid: 2차원 레이아웃
이러한 차이 때문에 Grid로는 구현이 어렵지만 Flex가 더 편리한 경우가 많이 존재한다.
만약 레이아웃을 만들 때 행, 열 중 하나만 다룬다면 Flex를, 둘 다 다룬다면 Grid를 고려해보자.
(참고로 Safari에선 Flexbox가 동작하지 않는 이슈가 많다. 주의하자)
기본 구조
Flex 레이아웃은 부모인 flex-container가 자식인 flex-item들을 감싸는 형태로 구성된다.
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
속성
크게 flex-container와 flex-item에 적용되는 속성들로 나뉜다.
- flex-container 속성
display
flex-direction
flex-wrap
flex-flow
justify-content
align-items
align-content
- flex-item 속성
align-self
flex-basis
flex-grow
flex-shirink
flex
order
1. flex-container 속성
1.1 display
Flex를 사용하기 위해선 container의 display
속성에 flex
를 지정한다.
(container가 inline 요소인 경우 inline-flex
를 지정한다.)
.flex-container {
display: flex;
}
.flex-container {
display: inline-flex;
}
1.2 flex-direction
item이 배치될 주축 방향(main axis)을 설정한다.
- main axis(주축): 아이템들이 배치되는 방향
- cross axis(수직축, 교차축): 주축과 수직 방향
.flex-container {
flex-direction: row;
}
flex-direction: row
- 좌에서 우로 수평 배치 (기본값)flex-direction: row-reverse
- 우에서 좌로 수평 배치flex-direction: column
- 위에서 아래로 수직 배치flex-direction: column-reverse
- 아래에서 위로 수직 배치
1.2 flex-wrap
container보다 item들의 폭이 넓을 때 한 줄로 배치할지 여러 줄로 배치할지 결정한다.
.flex-container {
flex-wrap: nowrap;
}
flex-wrap: nowrap
- item들을 한 줄로 배치. 이때 item의 폭은 container에 맞게 축소됨 (기본값)flex-wrap: wrap
- item들의 폭이 container보다 클 경우 여러 줄로 배치flex-wrap: wrap-reverse
- flex-wrap: wrap;과 동일하나 아래에서 위로 배치
1.3 flex-flow
flex-direction
과 flex-wrap
을 한 번에 설정할 수 있다. (기본값: row nowrap)
.flex-container {
flex-flow: row nowrap; /* default */
}
1.4 justify-content
item의 주축(main axis) 정렬방법을 선택한다.
.flex-container {
justify-content: flex-start;
}
justify-content: flex-start
- 좌측 기준 정렬 (기본값)justify-content: flex-end
- 우측 기준 정렬justify-content: center
- 가운데 정렬justify-content: space-between
- item 사이 간격이 균등하게 정렬justify-content: space-around
- item 좌우 여백(padding)이 균등하게 정렬
1.5 align-items
item 줄의 수직(cross axis) 정렬방법을 선택한다.
.flex-container {
align-items: stretch;
}
align-items: stretch
- item의 높이를 container에 꽉 차게 정렬 (기본값)align-items: flex-start
- item을 container의 시작에 맞춰 정렬align-items: flex-end
- item을 container의 끝에 맞춰 정렬align-items: center
- item을 container의 중앙에 맞춰 정렬align-items: baseline
item을 텍스트 베이스라인 기준으로 정렬
1.6 align-content
flex-wrap: wrap
일 때 생기는 여러 item 줄의 수직(cross axis) 정렬 방법을 선택한다.
.flex-container {
align-content: stretch;
}
align-content: stretch
- item 줄의 높이를 container에 꽉 차게 정렬 (기본값)align-content: flex-start
- item 줄을 container의 시작에 맞춰 정렬align-content: flex-end
- item 줄을 container의 끝에 맞춰 정렬align-content: center
- item 줄을 container의 중앙에 맞춰 정렬align-content: space-between
- item 줄 사이 간격이 균등하게 정렬align-content: space-around
- item 줄 상하 여백(padding)이 균등하게 정렬
2. flex-item 속성
2.1 order
item 각각의 배치 순서를 지정할 수 있다. (기본값: 0)
시각적 순서만 변경될 뿐 HTML 구조 자체를 변경하지 않으니 접근성 목적에서의 사용은 주의해야 한다.
.flex-item:nth-child(1) {
order: 3;
}
.flex-item:nth-child(2) {
order: 1;
}
.flex-item:nth-child(3) {
order: 2;
}
2.2 flex-grow
item이 기본 크기(flex-basis
)의 값보다 얼마나 커질지 결정한다. (기본값: 0)
item의 flex-basis
를 제외한 여백을 flex-grow
값의 비율만큼 나누어 가진다고 보면 된다.
.flex-item {
flex-grow: 양의 정수; /* 음수 불가 */
}
2.3 flex-shrink
item이 기본 크기(flex-basis
)의 값보다 얼마나 작아질지 결정한다. (기본값: 1)
값으로 0을 주면 기본 크기보다 작아지지 않아 고정폭의 레이아웃을 만들기 용이하다.
.flex-item {
flex-shrink: 양의 정수; /* 음수 불가 */
}
2.4 flex-basis
item의 기본 크기를 설정한다. (기본값: auto)
이때 auto
는 해당 item의 width가 된다. width를 설정하지 않았다면 컨텐츠의 크기가 된다.
.flex-item {
flex-basis: auto; /* 기본값 */
flex-basis: 0;
flex-basis: 20%;
flex-basis: 100px;
flex-basis: 2rem;
flex-basis: content; /* 컨텐츠의 크기 */
}
2.5 flex
flex-grow
, flex-shrink
, flex-basis
를 한 번에 설정할 수 있다. (기본값: 0 1 auto)
세 속성이 관련 깊기 때문에 묶어서 쓰는 일이 자주 있다. 확실히 익혀두는 것을 추천한다!
.flex-item {
flex: initial; /* flex: 0 1 auto */ /* 기본값 */
flex: auto; /* flex: 1 1 auto */
flex: none; /* flex: 0 0 auto */
flex: 2 2 10%;
}
2.6 align-self
item 각각의 수직(cross axis) 정렬방법을 선택한다. (기본값: auto)
헷갈릴 수 있는데 align-items
가 item 줄의 수직 정렬이라면, align-self
는 item 각각의 수직 정렬이다.
.flex-item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
3. Flexbox playground
아래 사이트에서 속성들을 만지다 보면 금방 익숙해질 것이다!
See the Pen Flexbox playground by Gabi (@enxaneta) on CodePen.