문제 상황
화면 크기를 조금만 줄여도 아래 이미지처럼 웹 페이지가 깨져 보인다.

목표
화면 크기에 상관 없이 웹 페이지가 깨지지 않도록 하고 싶다. -> CSS Flex 를 이용한다!

CSS Flex /Container기초 이론
아래와 같은 코드를 본 적이 있는가?
<div class="container"> <!-- flex container -->
<div class="item">하이1</div> <!-- flex item -->
<div class="item">하이2</div> <!-- flex item -->
<div class="item">하이3</div> <!-- flex item -->
</div>
컨테이너를 하나 만든 것을 flex container 라고 부르고, 컨테이너 안의 요소들을 flex item 이라고 부른다.
조금 더 쉽게 이해하기 위해서는 아래 그림을 살펴보자.
어떤 요소들이 컨테이너에 담겨져 있는데, 컨테이너 박스 자체를 flex container 라고 부르고 컨테이너 안의 요소들을 flex item 이라고 부르는 것이다.
CSS Container 개념의 핵심은 컨테이너 크기가 늘어나거나 줄어들어도 항상 flex item들은 container 안에 있어야 한다는 것이 핵심이다.

그래서 아까의 목표에 있던 움짤처럼 컨테이너 크기가 줄어들어도 깨지지 않고 컨테이너 요소 안에 들어가 있는 것이다.
이 것을 도와주는 것이 display:flex; 이라는 것이다.
우리가 지금까지 이야기 했던 container가 되려면 display:flex; 을 추가해야 한다.
<!-- HTML -->
<div class="container"> <!-- flex container -->
<div class="item">하이1</div> <!-- flex item -->
<div class="item">하이2</div> <!-- flex item -->
<div class="item">하이3</div> <!-- flex item -->
</div>
/* CSS */
.container {
display:flex;
}
flex 문법 - flex container에 적용되는 것들
1) flex-direction
- 컨테이너의 아이템들이 배치되는 축의 방향을 나타낸다.
- 기본값은 row이다.
✅flex-direction:row;

✅flex-direction:column;

2) flex-wrap
- 줄넘김 설정을 바꿔준다.
- 기본값은 nowrap이다.
✅flex-wrap:nowrap;
줄넘김을 하지 않는다.

✅flex-wrap:wrap;
여유 공간이 없으면 줄바꿈을 한다.

✅flex-wrap:wrap-reverse;
여유 공간이 없으면 줄바꿈을 반대로 한다.

3) justify-content
- 메인축(가로) 방향으로 정렬
메인축 = 가로(꼬치를 끼는 방향) / 교차축 = 세로 (꼬치에서 위로 떼어내는 방향)

✅justify-content: space-between;
화면과 딱 맞도록 한다.

✅justify-content: space-around;
영역을 똑같이 가지고 그 영역에서 가운데 정렬한다.

✅justify-content: space-evenly;
똑같은 간격을 가진다.

⭐justify-content: center;
가운데 정렬

✅justify-content: flex-end;
오른쪽 정렬

4) align-items
- 교차축(세로) 방향으로 정렬
✅align-items: flex-end;
수직 아래쪽 기준으로 정렬

⭐align-items: center;
수직 가운데 정렬

5) 어떤 요소를 가운데로 보내고 싶다면?
.test-container {
display:flex;
justify-content: center; /* 수평 가운데 정렬 */
align-items:center; /* 수직 가운데 정렬 */
}

flex 문법 - flex item에 적용되는 것들
1) flex-basis
- flex item 요소의 가로 크기를 지정
- 기본값 : auto
.item {
flex-basis: auto; /* default */
/* flex-basis: 0; */
/* flex-basis: 15%; */
/* flex-basis: 200px; */
/* flex-basis: 10rem; */
/* flex-basis: content; */
}
✅flex-basis: 15%;
각 칸이 전체 가로 영역의 15%를 차지하도록 지정

✅flex-basis: content;
안에 있는 내용을 기준으로 가로 크기 지정

2) flex-grow
- flex item 요소의 여백을 정해진 비율에 따라 나눠 가진다.
- 기본값 : 0 (0인 경우 여백을 나눠갖지 않음)
✅flex-grow: 1;
5개의 요소들이 남은 여백을 1:1:1:1:1로 나눠 갖는다.

✅.item:nth-child(1) {flex-grow : 0.1};
.item:nth-child(1) {flex-grow : 0.1}
.item:nth-child(2) {flex-grow : 1}
.item:nth-child(3) {flex-grow : 4}
.item:nth-child(4) {flex-grow : 0.5}
.item:nth-child(5) {flex-grow : 0.2}
5개 요소들이 각각 남은 여백을 0.1 : 1 : 4 : 0.5 : 0.2 로 나눠 갖는다.

3) flex-shrink
- flex-basis 보다 작아질 수 있는지 결정
- 기본값 : 1 (0인 경우 flex-basis보다 작아질 수 없음, 1인 경우 작아질 수 있음.)
✅flex-shrink: 1;
4) flex
- flex-grow, flex-shrink, flex-basis 를 한 번에 지정할 수 있도록 한다.
.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 200px;
/* flex-grow: 1; flex-shrink: 1; flex-basis: 200px; */
}
5) align-self
- flex item의 수직축 정렬 (align-items)의 item 버전
- 기본값 : auto
.item {
align-self: auto;
/* align-self: stretch; */
/* align-self: flex-start; */
/* align-self: flex-end; */
/* align-self: center; */
/* align-self: baseline; */
}
✅align-self: flex-end;
각 아이템에서 수직 기준으로 아래 정렬

어떤 단위로 container를 잡아야 할까?
- 같이 가야하는 운명공동체 요소인 경우
- 반복되는 요소들이 있는 경우
- 참고로 finder 라이브러리에서 사용한 input 박스나 summernote 라이브러리 등 부트스트랩 류의 라이브러리 사용 시 container가 자동 적용되어 있다.
- 아래 이미지에서 묶은 단위들마다 container을 만들면 된다.
- 바깥 배경 색이 연보라색이고 안의 배경색이 흰색이므로 흰색쪽에 해당하는 전체 컨테이너를 잡고, 그 안에서 섹터별로 요소를 정해 컨테이너로 만든다.
- 제목과 제목을 입력하는 인풋박스는 같이 이동해야 하므로 이 둘을 묶고, 주제선택과 아래 텍스트도 같이 이동해야 하는 요소이므로 이 둘을 묶고, 정보제공/후기/질문 탭을 요소로 묶는다.
- 정보제공/후기/질문은 각각 반복되는 요소이므로 세부 요소로 묶는다. (정보제공에는 부동산 정책/투자, 부동산 핫이슈 버튼이 같이 움직여야 하므로)

이렇게 컨테이너화를 하면 좋은 것은 갑자기 변동사항이 생겨도 쉽게 수정이 가능하다는 것이다.
예를 들면 주제선택에 세부 항목으로 정보제공/후기/질문에서 하나가 더 추가된 경우 컨테이너를 만들어(display:flex;) justify-content:space-around; 을 사용한다면 위치 걱정 없이 쉽게 해결할 수 있다.
flex 문법 공부하기 좋은 사이트
Flexbox Froggy
A game for learning CSS flexbox
flexboxfroggy.com