flexbox는 하나의 container와 여러 개의 item으로 구성된다.
다양한 flex 관련 속성들을 container에 적용하는 속성과 item에 적용하는 속성으로 나눌 수 있다.
기본 CSS 구성
.container {
width: 400px;
height: 100px;
background: green;
padding: 0.5rem;
}
.item {
color: black;
font-size: 30px;
padding: .5rem;
text-align: center;
}
.container {
display: flex;
/* display: inline-flex; */
}

컨테이너에 display: flex; 를 적용하는 것이 가장 기본이다.
flex 속성의 컨테이너 안의 아이템들은 inline 요소들처럼 자신의 내용물만큼의 width를 차지하며 가로 방향으로 배치되게 된다. 그리고 컨테이너의 height만큼 쭉 늘어난다.
inline-flex와 flex의 경우는 inline과 inline-block의 관계와 비슷하다.
아이템들이 배치되는 축의 방향을 결정한다.
기본적으로 아이템들이 정렬되어 있는 방향의 축을 main axis 라고 하고, 그 축과 수직인 축을 cross axis라고 한다.
main axis는 flex-direction 속성을 따르며, 기본값은 row 이다.
flex-direction 값을 column으로 설정해 주면 아이템들이 세로로 배치된다.

그리고 row-reverse 혹은 column-reverse 속성은 역순으로, 즉 오른쪽에서 왼쪽 방향, 혹은 아래쪽에서 위쪽 방향으로 배치한다. 그림은 생략하겠지만 row-reverse로 설정하면 C B A 순서대로 배치된다.
컨테이너가 아이템을 한 줄로 표시할 여유 공간이 없을 때, 아이템들의 줄바꿈을 결정하는 속성이다.
.container {
flex-wrap: nowrap;
/* flex-wrap: wrap; */
/* flex-wrap: wrap-reverse; */
}
기본값은 nowrap이며 넘치면 그냥 옆으로 삐져 나간다.
wrap 으로 설정해 주게 되면 줄바꿈이 작용한다.

위의 두가지 속성들을 한번에 지정하는 속성이다.
.container {
flex-flow: row wrap;
/* 아래의 두 줄을 줄여 쓴 것 */
/* flex-direction: row; */
/* flex-wrap: wrap; */
}
아이템을 어떻게 정렬할 것인지 중에서, main-axis 방향에 대한 속성을 다룬다.
.container {
justify-content: flex-start;
/* justify-content: flex-end; */
/* justify-content: center; */
/* justify-content: space-between; */
/* justify-content: space-around; */
/* justify-content: space-evenly; */
}
기본값은 flex-start 이며 시작점으로부터 정렬한다.
flex-end는 끝에서부터 역순으로 정렬한다.
center는 가운데로 정렬한다.
space-between은 아이템의 사이에 균일한 간격을 만든다.
space-around는 아이템의 둘레에 균일한 간격을 만든다.
space-evenly는 아이템의 사이 및 양 끝에 균일한 간격을 만든다.

cross-axis 방향으로 정렬하는 속성을 다룬다.
.container {
align-items: stretch;
/* align-items: flex-start; */
/* align-items: flex-end; */
/* align-items: center; */
/* align-items: baseline; */
}
stretch는 컨테이너의 높이만큼 쭉 늘어난다.
flex-start,end와 center는 justify와 같다.
baseline은 text baseline 기준으로 정렬한다.
즉
justify-content: center;
align-item: center;
를 해주면 아이템을 한 가운데에 배치할 수 있다.
.container {
flex-wrap: wrap;
align-content: stretch;
/* align-content: flex-start; */
/* align-content: flex-end; */
/* align-content: center; */
/* align-content: space-between; */
/* align-content: space-around; */
/* align-content: space-evenly; */
}
줄바꿈이 된 상태에서 아이템이 여러 행일 때의 정렬 방법을 결정한다.
아이템의 기본 크기를 설정한다.
.item {
flex-basis: 100px;
}
만약 basis를 100px로 설정하면, 100px보다 작은 크기의 아이템들도 100px로 크기가 늘어난다. 크기가 100px보다 큰 아이템들은 변화가 없다. (이것이 width와 다른 점이다. width 속성은 크기가 더 큰 아이템도 줄여 버린다.)

원래 이랬다가

basis를 70px로 적용해서 기본 크기가 늘어난 모습이다.
아이템이 basis보다 커질 수 있는지를 나타낸다.
.item {
flex-grow: 1;
/* flex-grow: 0; */ /* 기본값 */
}
기본값은 0이다. 즉 basis보다 커질 수 없어서 여백이 남게 된다.

1로 고쳐주면 아이템들이 늘어나면서 여백을 채운다.

이 때, flex-grow에 지정해 준 숫자가 영향을 미친다.
남은 여백을 지정해준 비율 만큼 나눠서 먹는다.
이 말이 무슨 말인고 하니 예시를 보자.
.yellow {
background: yellow;
flex-grow: 1;
}
.orange {
background: orange;
flex-grow: 2;
}
.blue {
background: aqua;
flex-grow: 3;
}

각각 yellow, orange, aqua 클래스에다가 1, 2, 3씩을 지정해 주었다.
그리고 각 상자의 여백을 보면, 컨텐츠를 표시하고 남은 부분이 총 여백을 1:2:3만큼 나눠 가진 것을 볼 수 있다. 즉 나눠 가지는 비율을 나타낸다.
여기에서 만약에 grow가 1로 설정되어 있고 basis도 0이 아니라면, 컨텐츠의 크기와 상관없이 basis 기준으로 비율만큼 나눠 갖는다는 것을 유의.
flex-grow는 basis보다 커지는 것을 다루었다면 shrink는 반대로 작아지는 것을 다룬다.
.item {
flex-basis: 150px;
flex-shrink: 1; /* 기본값 */
}
기본값은 1이며, 0으로 설정해 주면 basis보다 작아지지 않는다.
basis보다 작아지지 않는다는 점을 이용해서, 컨테이너의 크기가 바뀌어도 고정된 폭의 아이템을 만드는 데 유용하다.
basis, grow, shrink를 한번에 설정할 수 있다.
.item {
flex: 1;
/* flex-grow: 1; flex-shrink: 1; flex-basis: 0%; */
flex: 1 1 auto;
/* flex-grow: 1; flex-shrink: 1; flex-basis: auto; */
flex: 1 500px;
/* flex-grow: 1; flex-shrink: 1; flex-basis: 500px; */
}
위의 예시와 같이 grow, shrink, basis 순서대로 지정해 줄 수 있다.
만약 flex: 1; 로 설정해 주면 grow가 1, shrink가 1, basis가 0으로 설정된다. 즉 전체 컨테이너를 각 아이템들이 같은 크기로 나눠 먹는다.

다른 예시를 보자.
.container {
display: flex;
flex-wrap: wrap;
}
.item {
flex: 1 1 40%;
}
container에서 flex-wrap 속성을 wrap으로 설정해 주고(줄바꿈을 활성화 해주고), flex를 1 1 40%으로 설정해 주면 어떻게 될까?

한 아이템당 basis가 40%이기 때문에 한 라인에 두개의 아이템만 들어갈 수 있게 되고 남은 여백을 1:1로 나눠먹어서 결과적으로 한 라인에 2등분하여 2개씩 정렬할 수 있게 된다.
같은 원리로 flex: 1 1 30%으로 해주면 한 라인에 3등분된 아이템이 3개씩 들어간다.
cross axis 방향의 정렬을 아이템 단위로 설정할 수 있다.
.item {
align-self: auto;
/* align-self: stretch; */
/* align-self: flex-start; */
/* align-self: flex-end; */
/* align-self: center; */
/* align-self: baseline; */
}
align-self는 align-items보다 우선권을 가진다.