edubun English

플렉스박스

플렉스박스 전에는 상자를 세로 가운데에 놓으려면 요령이 필요했습니다. display: flex가 있으면 justify-content와 align-items 선언 두 개면 됩니다.

한 줄 또는 한 칸

플렉스박스(CSS Flexible Box Layout 모듈)는 상자 여러 개를 한 줄을 따라 배치합니다. 부모에 display: flex를 주면 바로 아래 자식인 플렉스 항목들이 아래로 쌓이지 않고 옆으로 늘어섭니다. 이 선언 하나면 메뉴 막대, 버튼 줄, 꼬리말이 아래에 붙어 있어야 하는 카드를 만들 수 있습니다. 플렉스박스는 한 번에 한 방향, 그러니까 행이나 열 하나만 다룹니다. 행과 열을 함께 다루어야 한다면 다음 단원의 그리드가 대개 더 잘 맞습니다.

행(row)에서 주축은 왼쪽에서 오른쪽으로(영어·한국어 기준), 교차축은 위에서 아래로 향합니다. justify-content는 주축, align-items는 교차축을 따라 작동합니다.

두 개의 축

플렉스박스에서는 배치를 늘 두 축으로 설명합니다. 주축은 항목이 흘러가는 방향으로, 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 200pxgrow 1, shrink 1, basis 200px
  1. 요소를 플렉스 컨테이너로 만드는 선언은?
    • display: flex
    • flex: 1
    • position: flex
  2. 행에서 항목을 가로로 나누는 속성은?
    • justify-content
    • align-items
    • flex-wrap
  3. flex-direction: column에서 justify-content가 정하는 것은?
    • 세로 방향 배치
    • 가로 방향 배치
    • 글자 크기
  4. 첫 항목과 마지막 항목을 양 끝에 두고 사이를 같게 하는 값은?
    • space-between
    • space-around
    • center
  5. align-items의 기본값은?
    • stretch
    • center
    • flex-start
  6. 간격 없는 400px 컨테이너에 flex: 1인 항목이 4개입니다. 항목 너비는?
  7. flex-basis 0인 항목 3개가 400px를 나눕니다. 하나는 flex-grow 2, 나머지는 1입니다. 큰 항목의 너비는?
  8. flex-wrap: wrap은 무엇을 허용할까요?
    • 자리가 없으면 항목이 다음 줄로 넘어감
    • 항목 안의 글이 줄바꿈됨
    • 항목이 겹침
  9. order로 Contact를 화면 맨 앞에 두었지만 HTML에서는 마지막입니다. 여전히 마지막에 가는 것은?
    • 키보드 초점과 화면 낭독기
    • 마우스 포인터
    • 없음
  10. 플렉스박스는 한 번에 몇 방향을 배치할까요?
핵심 정리
  • display: flex는 바로 아래 자식을 주축을 따라 늘어놓습니다.
  • 주축은 justify-content, 교차축은 align-items, 사이는 gap.
  • flex: grow shrink basis. 다시 흘러야 하는 줄에는 flex-wrap: wrap. 보이는 순서는 HTML 순서와 같게.