[CSS] flexbox 총정리

ungnam·2023년 7월 13일

flexbox

flexbox를 사용하여 보다 강력하고 편리한 방식으로 HTML 요소들을 가로 또는 세로 방향으로 배치하고 간격을 조정하며 정렬할 수 있다.

flexbox는 주축(main axis)와 교차축(cross axis)라는 개념을 가지고 있다.
주축은 컨테이너 요소들이 배치되는 방향을 말하며, 디폴트는 가로 방향이다.
교차축은 주축에 수직으로 대응되는 방향을 말하며, 디폴트는 세로 방향이다.
flexbox의 동작은 결국 이 두 개의 축에 대한 문제로 환원되기 때문에 이들이 어떻게 동작하는지 이해하는 것이 중요하다.


flex 컨테이너에 적용하는 속성

justify-content

주축 방향으로 요소들을 정렬하는 속성이다.

(default 기준)

  • flex-start(default) : 요소들을 컨테이너의 왼쪽 끝에 정렬
  • flex-end : 요소들을 컨테이너의 오른쪽 끝에 정렬
  • center : 요소들을 컨테이너 주축 상의 중앙에 정렬

space-between, space-around, space-evenly에 대한 설명은 아래 그림과 같다.

align-items

교차축 방향으로 요소들을 정렬하는 속성이다.

(default 기준)

  • flex-start(default) : 요소들을 컨테이너의 꼭대기로 정렬
  • flex-end : 요소들을 컨테이너의 바닥으로 정렬
  • center : 요소들을 컨테이너의 세로선상의 중앙에 정렬
  • stretch : 요소들을 컨테이너에 맞도록 늘림
  • baseline : 요소들을 텍스트의 베이스라인 기준으로 정렬(아래 그림 참조)

baseline 예시

flex-direction

  • row : 요소들을 텍스트의 방향과 동일하게 정렬한다.
  • row-reverse : 요소들을 텍스트의 방향과 반대로 정렬한다.
  • column : 요소들을 위에서 아래로 정렬한다.
  • column-reverse : 요소들을 아래에서 위로 정렬한다.

row-reversecolumn-reverse를 사용하면 요소들의 startend의 순서도 뒤바뀐다.

flex의 방향이 column인 경우 justify-content에서의 기준 축이 세로 방향으로, align-items에서의 기준 축이 가로 방향으로 바뀐다.

flex-wrap

더 이상 요소들을 한 줄에 담을 여유공간이 없을 때 컨테이너가 요소 줄바꿈을 어떻게 할지 결정하는 속성이다.

  • no-wrap(default) : 줄바꿈을 하지 않는다. 요소들이 컨테이너의 너비를 초과할 경우 부모 너비에 맞게 자동으로 축소된다.
  • wrap : 요소들이 컨테이너의 너비를 초과할 경우 넘치는 요소를 다음 줄로 넘겨 정렬한다.
  • wrap-reverse : wrap과 유사하나 요소들이 반대로 정렬된다.

flex-flow

flex-directionflex-wrap을 한꺼번에 지정할 수 있는 단축 속성이다.
ex) flex-flow: row wrap;

align-content

flex-wrap: wrap이 설정된 상태에서 요소들이 2줄 이상 정렬되었을 때 줄 사이의 간격을 지정할 수 있는 속성이다.

flex-start, flex-end, center, space-between, space-around, space-evenly, stretch 값을 가지며 각 값이 가지는 의미는 앞서 설명한 내용과 동일하다.


flex 개별 요소에 적용하는 속성

align-self

align-items전체 요소에 대한 수직 정렬이라면, align-self는 해당되는 특정 요소에 대한 수직 정렬을 의미한다.
기본값은 auto로, 기본적으로 align-items의 속성을 상속받으며 나머지 속성은 align-items가 가지는 속성과 동일하다.

order

요소들의 나열되는 순서를 결정하는 속성으로 기본값은 0이며, 양수와 음수 값이 올 수 있다. 이 때 작은 숫자일수록 먼저 배치된다.

order시각적 순서를 변경할 뿐 HTML 자체의 구조를 바꾸는 것이 아니므로 접근성 측면에서 사용에 유의해야 한다.
시각장애인이 스크린 리더로 화면을 읽을 때 order를 통해 순서를 바꾼 것은 아무런 의미가 없다는 것을 기억하자.


#container {
  display: flex;
  border: 2px solid black;
  background-color: pink;
  width: 1000px;
  height: 200px;
}
.item {
  border: 1px solid black;
  background-color: powderblue;
  width: 100px;
  height: 100px;
  margin: 10px;
  line-height: 100px;
  text-align: center;
  font-size: 24px;
}

flex-basis

Flex 요소의 기본 크기를 결정하는 속성으로 flex-directionrow인 경우 너비를, column인 경우 높이를 결정한다.

✔ 기본값은 auto로, 이 경우 해당 요소가 가지고 있는 width(height) 값을 그대로 사용한다. 이 때 요소의 width(height)가 따로 지정되지 않은 경우 컨텐츠의 크기 자체를 값으로 갖는다.

.item:first-child {
  flex-basis: auto;
}

image

content로 설정한 경우 컨텐츠의 크기를 값으로 갖는다.

.item:first-child {
  flex-basis: content;
}

image

px, rem, em, %와 같은 단위도 들어갈 수 있다.

.item {
  border: 1px solid black;
  background-color: powderblue;
  /* width: 100px; */
  flex-basis: 100px;
  height: 100px;
  margin: 10px;
  line-height: 100px;
  text-align: center;
  font-size: 24px;
}

이 때 요소의 크기를 flex-basis로 설정하면 요소의 크기보다 컨텐츠의 크기가 더 큰 경우 컨텐츠만큼 요소의 크기가 늘어나게 된다. 반대로, width로 설정하면 컨텐츠의 크기가 더 클 경우 요소의 바깥 영역으로 컨텐츠가 빠져나오게 된다.

image

0인 경우 content의 크기를 무시하고 flex-grow, flex-shrink 설정 비율대로 요소의 width(height)를 배분한다. 아래 flex 속성에서 더 자세히 알아보자.

flex-grow

컨테이너에 공간이 남을 경우 요소의 flex-basis 값보다 더 커질 수 있는지를 결정하는 속성이다. 기본값은 0이며 이 경우 요소가 늘어나지 않는다.

.item {
  border: 1px solid black;
  background-color: powderblue;
  /* width: 100px; */
  /* flex-basis: 100px; */
  flex-grow: 1;
  height: 100px;
  margin: 10px;
  line-height: 100px;
  /* text-align: center; */
  font-size: 24px;
}

image

각 요소의 flex-grow0보다 큰 값이 세팅된 경우 해당 요소는 flexible한 박스로 변한다. 따라서 요소의 크기가 커지며 컨테이너의 빈 공간을 채우게 된다.

이 때 flex-grow에 들어가는 숫자의 의미는, 요소들의 flex-basis를 제외한 여백 부분을 flex-grow에 지정된 숫자의 비율로 나누어 가진다고 생각하면 된다.

마지막 요소에 flex-grow: 2를 주면,

.item:last-child {
  flex-grow: 2;
}

image
이렇게 flex-basis를 제외한 여백 부분이 1:1:1:1:1:2가 됨을 확인할 수 있다.

flex-shrink

반대로 컨테이너가 공간이 부족해질 때 요소의 flex-basis 값보다 더 작아질 수 있는지를 결정하는 속성이다. 기본값은 1이기 때문에 따로 세팅하지 않아도 요소가 flex-basis보다 더 작아질 수 있다.

#container {
  display: flex;
  border: 2px solid black;
  background-color: pink;
  /* width: 1000px; */
  /* height: 200px; */
  margin: 100px;
}
.item {
  border: 1px solid black;
  background-color: powderblue;
  width: 200px;
  height: 100px;
  margin: 10px;
  line-height: 100px;
  font-size: 24px;
}
.item:first-child {
  flex-basis: 200px;
  flex-shrink: 0;
}

image

image

컨테이너의 너비를 지정하지 않고 첫번째 요소에만 flex-shrink: 0을 준 결과, 컨테이너의 너비가 변해도 요소의 크기는 flex-basis의 값보다 더 작아지지 않고 고정되어 있는 것을 확인할 수 있다.

flex

flex-grow, flex-shrink, flex-basis를 한 번에 지정할 수 있는 축약형 속성이다. flex 속성에는 다음과 같은 규칙이 있다.

  1. 값이 한 개일 때
    ✔ 단위가 없으면 flex-grow
    ✔ 단위가 있으면 flex-basis
  2. 값이 두 개일 때
    ✔ 첫 번째 값은 단위가 없어야 하며, flex-grow에 해당한다.
    ✔ 두 번째 값은 단위가 있으면 flex-basis, 단위가 없으면 flex-shrink
  3. 값이 세 개일 때
    ✔ 첫 번째 값은 flex-grow, 두 번째 값은 flex-shrink, 세 번째 값은 flex-basis
#container {
  display: flex;
  border: 2px solid black;
  background-color: pink;
  /* width: 1000px; */
  /* height: 200px; */
  margin: 100px;
}
.item {
  border: 1px solid black;
  background-color: powderblue;
  width: 200px;
  height: 100px;
  margin: 10px;
  line-height: 100px;
  font-size: 24px;
  flex: 1;
}

image

flex: 1인 경우 flex-basis0이 된다. 이 경우 여백의 비가 아닌 영역 자체를 기준으로 1:1:1:1:1:1로 분할된다.


Reference
1분코딩 - 이번에야말로 CSS Flex를 익혀보자
FLEXBOX FROGGY

profile
꾸준함을 잃지 말자.

0개의 댓글