본문 바로가기

flex

1. 유연한 레이아웃을 위한 flex

Flexbox는 현대 웹 디자인에서 가장 많이 사용하고 강력한 레이아웃 도구 중 하나입니다. 1차원적 레이아웃(행 또는 열)을 쉽게 만들 수 있으며, 요소들의 크기와 순서를 동적으로 조절할 수 있습니다.

1.1 flex를 적용하는 방법

부모 요소를 display: flex로 설정하면 자식 요소들이 flex item이 되어 flexbox 레이아웃을 사용할 수 있습니다. 부모 요소를 flex-container 자식 요소를 flex-item 이라고 부릅니다. 이를 통해 자식들을 배치하고 정렬할 수 있습니다.

.container {
  display: flex;
}

1.2 flex-container에 사용하는 속성

1.2.1 주 축의 방향

flex-direction은 주축의 방향을 설정합니다. 기본값은 row입니다.

  • row : 기본값. 왼쪽에서 오른쪽 (주축이 행 방향)
  • column: 위에서 아래 방향 (주축이 열 방향)
  • row-reverse: 오른쪽에서 왼쪽
  • column-reverse: 아래에서 위 방향
<div class="container row">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

<div class="container column">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

<div class="container row-reverse">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

<div class="container column-reverse">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
.container {
  display: flex;
  margin-bottom: 10px;
  background-color: #f0f0f0;
  padding: 10px;
}

.row {
  flex-direction: row;
}
.column {
  flex-direction: column;
}
.row-reverse {
  flex-direction: row-reverse;
}
.column-reverse {
  flex-direction: column-reverse;
}

.item {
  background-color: #4967d8;
  color: white;
  padding: 10px;
  margin: 5px;
  text-align: center;
}

각 flex-direction 값의 효과를 직접 볼 수 있습니다. 이 속성은 flexbox 레이아웃의 주축 방향을 결정하므로, 전체적인 레이아웃 구조를 쉽게 변경할 수 있습니다. 특히 반응형 디자인에서 화면 크기에 따라 레이아웃을 조정할 때 유용하게 사용될 수 있습니다.

1.2.2 주축의 아이템 정렬

주축을 기준으로 배열의 위치를 조절하거나 아이템 간의 설정을 할 수 있습니다.

.container {
  justify-content: flex-start | flex-end | center | space-between | space-around
    | space-evenly;
}
  • flex-start: 시작점에 정렬
  • flex-end: 끝점에 정렬
  • center: 가운데 정렬
  • space-between: 아이템 사이에 동일한 간격을 설정
  • space-around: 아이템 주변에 동일한 간격을 설정
  • space-evenly: 아이템 주변과 시작과 끝에 동일한 간격을 설정

아래 예제에서 justify-content 속성을 사용해 아이템을 다양한 방식으로 배치해보세요.

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
.container {
  display: flex;
  justify-content: space-between;
  background-color: #f0f0f0;
  padding: 10px;
}
.item {
  background-color: #4967d8;
  color: white;
  padding: 10px;
  text-align: center;
  border-radius: 5px;
}

1.2.3 align-items

align-items는 교차 축을 기준으로 정렬합니다.

.container {
  align-items: stretch | flex-start | flex-end | center | baseline;
}
  • stretch: 기본값. 교차축을 채우기 위해 아이템을 늘립니다.
  • flex-start: 시작점에 정렬
  • flex-end: 끝점에 정렬
  • center: 가운데 정렬
  • baseline: 텍스트의 기준선에 정렬

이 속성을 이용하여 A박스를 아래와 같이 배치해보세요. 이 박스를 배치하는 방법은 한가지가 아닙니다. 다양한 방법으로 실습해보세요.

<div class="wrap">
  <div class="blue">A</div>
</div>
.wrap {
  background-color: gainsboro;
  width: 240px;
  height: 240px;
}

.wrap > div {
  color: white;
  line-height: 70px;
  text-align: center;
  font-size: 20px;
  width: 70px;
  height: 70px;
}

.blue {
  background-color: #4967d8;
}
  • 정답
    /* 추가 */
    .wrap {
      display: flex;
      flex-direction: row-reverse;
      align-items: center;
    }
    

1.2.4 align-content

align-content는 여러 줄의 flex 아이템들을 교차축 방향으로 정렬할 때 사용합니다. 이 속성은 flex-wrap: wrap이 설정되어 있고, 여러 줄의 flex 아이템이 있을 때만 효과가 있습니다.

.container {
  align-content: flex-start | flex-end | center | space-between | space-around |
    stretch;
}
  • flex-start: 여러 줄들을 컨테이너의 시작점으로 정렬합니다.
  • flex-end: 여러 줄들을 컨테이너의 끝점으로 정렬합니다.
  • center: 여러 줄들을 컨테이너의 세로선 상의 가운데로 정렬합니다.
  • space-between: 여러 줄들 사이에 동일한 간격을 둡니다.
  • space-around: 여러 줄들 주위에 동일한 간격을 둡니다.
  • stretch: 여러 줄들을 컨테이너에 맞도록 늘립니다.
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
</div>
.container {
  display: flex;
  flex-wrap: wrap;
  align-content: space-between;
  height: 200px;
  background-color: #f0f0f0;
}
.item {
  width: 30%;
  height: 50px;
  background-color: #4967d8;
  color: white;
  margin: 5px;
  text-align: center;
  line-height: 50px;
}

align-content와 align-items의 차이점에 주의하세요. align-items는 각 flex 라인 내에서 아이템들을 정렬하는 반면, align-content는 여러 줄 자체를 정렬합니다.

1.2.5 gap

아이템 사이의 간격을 설정할 때 사용 할 수 있는 속성입니다.

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
</div>
.container {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 20px; /* 행간 10px, 열간 20px */
  background-color: #f0f0f0;
  padding: 10px;
  width: 300px;
}

.item {
  background-color: #4967d8;
  color: white;
  padding: 20px;
  text-align: center;
  flex-basis: calc(33.33% - 20px); /* 3열 레이아웃, gap 고려 */
}

이 예제에서 gap: 10px 20px;는 행 사이에 10px, 열 사이에 20px의 간격을 만듭니다.

1.2.6 flex-wrap

한 줄에 배치되게 할 것인지, 가능한 영역 내에서 여러 행으로 나누어 표현할 것인지 결정합니다.

  • nowrap: 모든 아이템을 한 줄에 표시합니다 (기본값).
  • wrap: 필요시 여러 줄에 걸쳐 아이템을 표시합니다.
  • wrap-reverse: wrap과 비슷하지만 아이템 행의 순서가 역전됩니다.
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
</div>
.container {
  display: flex;
  flex-wrap: wrap; /* nowrap, wrap, wrap-reverse */
  background-color: #f0f0f0;
  padding: 10px;
  width: 300px;
}

.item {
  background-color: #4967d8;
  color: white;
  padding: 20px;
  margin: 5px;
  text-align: center;
  flex-basis: 40%; /* 각 아이템의 기본 크기를 컨테이너의 40%로 설정 */
}

이 예제에서 flex-wrap: wrap;은 컨테이너의 폭을 넘어가는 아이템들을 다음 줄로 넘기도록 설정합니다. flex-wrap 값을 nowrap이나 wrap-reverse로 변경해보며 그 차이를 확인해보세요.

1.2.7 flex-flow

flex-flow는 flex-direction과 flex-wrap의 단축 속성입니다. 이 두 속성을 한 번에 지정할 수 있어 코드를 간결하게 만들 수 있습니다.

.container {
  flex-flow: <flex-direction> <flex-wrap>;
}

1.3 flex-item에 사용하는 속성

flex-item은 flex 컨테이너 내부의 개별 요소들을 말합니다. 이 요소들의 크기와 정렬을 더 세밀하게 제어하기 위해 다음과 같은 속성들을 사용할 수 있습니다.

1.3.1 flex-basis

flex-basis는 flex-item의 초기 크기를 설정합니다. 기본값은 auto입니다. width나 height와 다른 점은 축의 방향에 따라 달라진다는 것과 내부 콘텐츠에 따라 유연한 크기를 가진다는 것입니다. flex-direction이 row일 경우 width 값이, column일 경우 height 값이 무시됩니다.

<div class="container">
  <div class="item basis-auto">auto</div>
  <div class="item basis-0">0</div>
  <div class="item basis-100">100px</div>
  <div class="item basis-200">200px</div>
</div>
.container {
  display: flex;
  width: 500px;
  background-color: #f0f0f0;
}
.item {
  padding: 10px;
  background-color: #4967d8;
  color: white;
  margin: 5px;
}
.basis-auto {
  flex-basis: auto;
}
.basis-0 {
  flex-basis: 0;
}
.basis-100 {
  flex-basis: 100px;
}
.basis-200 {
  flex-basis: 200px;
}

주의

flex-basis에는 기본적으로 px이나 em 등의 단위값을 사용하며, 0 외에 다른 상숫값을 사용할 수 없습니다.

1.3.2 flex-grow

flex-grow는 아이템이 flex 컨테이너 내부에서 할당할 수 있는 공간의 비율을 지정합니다. 값이 0일 경우 아이템은 늘어나지 않습니다. 모든 아이템의 flex-grow 값이 1이면, 컨테이너 내부에서 동일한 크기의 공간을 할당받습니다. 특정 아이템의 값이 2 이상이면, 다른 아이템보다 해당 배수만큼 더 많은 공간을 할당받습니다.

<div class="container">
  <div class="item grow-0">0</div>
  <div class="item grow-1">1</div>
  <div class="item grow-2">2</div>
  <div class="item grow-1">1</div>
</div>
.container {
  display: flex;
  width: 500px;
  background-color: #f0f0f0;
}
.item {
  padding: 10px;
  background-color: #4967d8;
  color: white;
  margin: 5px;
  text-align: center;
}
.grow-0 {
  flex-grow: 0;
}
.grow-1 {
  flex-grow: 1;
}
.grow-2 {
  flex-grow: 2;
}

참고

flex-basis: 0을 설정하면 여백 공간이 아닌 전체 공간을 분할합니다.

1.3.3 flex-shrink

flex-shrink는 아이템의 크기를 축소할 때 사용합니다. 값이 0일 경우 아이템은 축소되지 않습니다. 값이 클수록 더 많이 축소됩니다.

<div class="container">
  <div class="item shrink-0">0</div>
  <div class="item shrink-1">1</div>
  <div class="item shrink-2">2</div>
  <div class="item shrink-3">3</div>
</div>
.container {
  display: flex;
  width: 300px;
  background-color: #f0f0f0;
}
.item {
  flex-basis: 100px;
  padding: 10px;
  background-color: #4967d8;
  color: white;
  margin: 5px;
  text-align: center;
}
.shrink-0 {
  flex-shrink: 0;
}
.shrink-1 {
  flex-shrink: 1;
}
.shrink-2 {
  flex-shrink: 2;
}
.shrink-3 {
  flex-shrink: 3;
}

1.3.4 align-self

align-self는 개별 flex-item에 대해 교차축 정렬을 지정합니다. 이 속성은 부모의 align-items 속성을 덮어씁니다. 기본값은 auto로, 부모의 align-items 값을 상속받습니다.

<div class="container">
  <div class="item self-start">start</div>
  <div class="item self-center">center</div>
  <div class="item self-end">end</div>
  <div class="item">auto</div>
</div>
.container {
  display: flex;
  height: 200px;
  background-color: #f0f0f0;
  align-items: stretch;
}
.item {
  width: 100px;
  background-color: #4967d8;
  color: white;
  margin: 5px;
  text-align: center;
}
.self-start {
  align-self: flex-start;
}
.self-center {
  align-self: center;
}
.self-end {
  align-self: flex-end;
}

1.3.5 order

order 속성은 flex-item의 순서를 지정합니다. 기본값은 0이며, 값이 작을수록 앞쪽에 배치됩니다.

<div class="container">
  <div class="item order-3">3</div>
  <div class="item order-1">1</div>
  <div class="item order-4">4</div>
  <div class="item order-2">2</div>
</div>
.container {
  display: flex;
  background-color: #f0f0f0;
}
.item {
  width: 70px;
  height: 70px;
  background-color: #4967d8;
  color: white;
  margin: 5px;
  text-align: center;
  line-height: 70px;
}
.order-1 {
  order: 1;
}
.order-2 {
  order: 2;
}
.order-3 {
  order: 3;
}
.order-4 {
  order: 4;
}

팁

order 속성은 논리적인 마크업 순서를 유지하면서 시각적인 순서를 변경할 때 유용합니다.

1.3.6 flex

flex는 flex-grow, flex-shrink, flex-basis의 단축 속성입니다.

.item {
  flex: 1 1 100px; /* flex-grow: 1, flex-shrink: 1, flex-basis: 100px */
}

이 속성들을 조합하여 사용하면 flex-item의 크기와 동작을 매우 세밀하게 제어할 수 있습니다.

2. 참고할 만한 링크

더 많은 flex 속성을 알고 싶다면 아래 링크를 참고하세요.

제주코딩베이스캠프 Flexbox | MDN flexngrid Flexbox Froggy