플렉스박스
플렉스박스 전에는 상자를 세로 가운데에 놓으려면 요령이 필요했습니다. display: flex가 있으면 justify-content와 align-items 선언 두 개면 됩니다.
한 줄 또는 한 칸
플렉스박스(CSS Flexible Box Layout 모듈)는 상자 여러 개를 한 줄을 따라 배치합니다. 부모에 display: flex를 주면 바로 아래 자식인 플렉스 항목들이 아래로 쌓이지 않고 옆으로 늘어섭니다. 이 선언 하나면 메뉴 막대, 버튼 줄, 꼬리말이 아래에 붙어 있어야 하는 카드를 만들 수 있습니다. 플렉스박스는 한 번에 한 방향, 그러니까 행이나 열 하나만 다룹니다. 행과 열을 함께 다루어야 한다면 다음 단원의 그리드가 대개 더 잘 맞습니다.
두 개의 축
플렉스박스에서는 배치를 늘 두 축으로 설명합니다. 주축은 항목이 흘러가는 방향으로, flex-direction이 정합니다. row(기본값)나 column입니다. 교차축은 주축과 직각으로 놓입니다. justify-content는 주축을 따라 항목을 나눠 놓습니다. flex-start, center, flex-end, space-between(첫 항목과 마지막 항목을 양 끝에 두고 사이를 같게), space-around가 있습니다. align-items는 교차축에서의 위치를 정합니다. stretch(기본값. 모든 항목을 가장 큰 항목만큼 늘림), flex-start, center, flex-end가 있습니다. 그러니 justify-content: center와 align-items: center를 함께 주면 상자가 가로세로 모두 가운데에 놓입니다.
.bar {
display: flex;
justify-content: space-between; /* logo left, menu right */
align-items: center; /* vertically centred */
gap: 16px; /* space between items */
}
.cards { display: flex; flex-wrap: wrap; gap: 12px; }
.card { flex: 1 1 200px; } /* grow, shrink, start at 200px */간격과 줄바꿈
gap은 바깥 가장자리에는 간격을 더하지 않고 항목 사이에만 간격을 둡니다. 대개 원하는 모습이 이것이고, margin으로는 만들기 까다로운 모습이기도 합니다. 기본으로 플렉스 항목은 찌그러지더라도 한 줄에 머물며 줄어듭니다. flex-wrap: wrap을 주면 자리가 모자랄 때 다음 줄로 넘어갑니다. 그러면 노트북에서 한 줄에 네 개인 카드가 태블릿에서는 두 개씩 두 줄, 휴대전화에서는 한 줄에 하나가 됩니다. 미디어 쿼리도 필요 없습니다.
항목이 늘고 줄어드는 방식
항목에 주는 flex 줄임 속성은 값 세 개를 받습니다. flex-grow는 남는 공간을 형제 항목과 비교해 얼마나 가져갈지, flex-shrink는 공간이 모자랄 때 얼마나 줄어들지, flex-basis는 늘거나 줄기 전의 처음 크기입니다. flex: 1 1 200px는 200픽셀에서 시작해, grow가 1인 다른 항목들과 남는 공간을 똑같이 나눠 갖는다는 뜻입니다. flex: 1만 쓰면 1 1 0%의 줄임이어서 모든 항목의 너비가 같아집니다. 항목 하나에 flex-grow: 2, 나머지에 1을 주면 그 항목이 남는 공간을 다른 항목의 두 배만큼 가져갑니다.
보이는 순서와 실제 순서
플렉스박스는 flex-direction: row-reverse나 order 속성으로 HTML을 건드리지 않고 항목이 보이는 순서를 바꿀 수 있습니다. 조심해서 쓰세요. 키보드 초점과 화면 낭독기는 여전히 HTML 순서를 따르므로, 화면에는 Contact가 Home보다 앞에 보이는데 Tab은 Home에 먼저 가면 키보드 사용자는 헷갈립니다. 순서가 뜻에 영향을 준다면 HTML에서 바꾸세요.
| 플렉스 컨테이너 | display: flex를 준 부모 |
| 플렉스 항목 | 플렉스 컨테이너의 바로 아래 자식 |
| 주축 | 흐르는 방향. flex-direction이 정함 |
| justify-content | 주축을 따라 항목을 배치 |
| align-items | 교차축에서 항목 위치를 정함 |
| gap | 항목 사이 간격. 가장자리에는 없음 |
| flex: 1 1 200px | grow 1, shrink 1, basis 200px |
- 요소를 플렉스 컨테이너로 만드는 선언은?
- display: flex
- flex: 1
- position: flex
- 행에서 항목을 가로로 나누는 속성은?
- justify-content
- align-items
- flex-wrap
- flex-direction: column에서 justify-content가 정하는 것은?
- 세로 방향 배치
- 가로 방향 배치
- 글자 크기
- 첫 항목과 마지막 항목을 양 끝에 두고 사이를 같게 하는 값은?
- space-between
- space-around
- center
- align-items의 기본값은?
- stretch
- center
- flex-start
- 간격 없는 400px 컨테이너에 flex: 1인 항목이 4개입니다. 항목 너비는?
- flex-basis 0인 항목 3개가 400px를 나눕니다. 하나는 flex-grow 2, 나머지는 1입니다. 큰 항목의 너비는?
- flex-wrap: wrap은 무엇을 허용할까요?
- 자리가 없으면 항목이 다음 줄로 넘어감
- 항목 안의 글이 줄바꿈됨
- 항목이 겹침
- order로 Contact를 화면 맨 앞에 두었지만 HTML에서는 마지막입니다. 여전히 마지막에 가는 것은?
- 키보드 초점과 화면 낭독기
- 마우스 포인터
- 없음
- 플렉스박스는 한 번에 몇 방향을 배치할까요?
- display: flex는 바로 아래 자식을 주축을 따라 늘어놓습니다.
- 주축은 justify-content, 교차축은 align-items, 사이는 gap.
- flex: grow shrink basis. 다시 흘러야 하는 줄에는 flex-wrap: wrap. 보이는 순서는 HTML 순서와 같게.