프론트엔드/CSS

[CSS] Flex (Flexbox)

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-containerflex-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를 사용하기 위해선 containerdisplay 속성에 flex를 지정한다.

(containerinline 요소인 경우 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-directionflex-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.

 

 

참조