CSS flexbox: 싸우지 않고 행 레이아웃하기

Flexbox는 한 줄의 항목을 위한 것입니다. 레이블, 남은 공간을 차지하는 막대, 오른쪽의 숫자, 모두 세로 중앙에 공백이 있습니다. 네 가지 패턴이 거의 모든 행을 덮고 있으며, 축소를 거부하는 하위 패턴인 하나의 함정이 대부분의 오버플로 버그를 설명합니다.

영문 원문 보기

CSS flexbox는 요소의 하위 요소를 가로 또는 세로의 한 줄을 따라 정렬하고 공간을 공유하는 방법을 결정합니다. 즉, 크기를 유지하는 요소, 남은 요소를 흡수하는 요소, 정렬 방식, 사이에 배치되는 요소 등을 결정합니다.

마크업. 강조 표시된 줄이 이 용어에 관한 부분입니다.
마크업. 강조 표시된 줄이 이 용어에 관한 부분입니다.

행에는 올바른 도구이고 카드 그리드에는 잘못된 도구입니다. 이것이 CSS 그리드의 목적입니다.

이 가이드에서는 대부분의 행을 처리하는 네 가지 패턴, 휴대폰에서 오버플로를 일으키는 축소 트랩, 정렬, 일반적인 페이지에서 Flexbox와 그리드가 작업을 분할하는 방법을 다룹니다.

.bar {
  display: flex;
  align-items: center;
  gap: 14px;
}

항목은 수직 중앙에 일정한 간격으로 일렬로 배치됩니다. 세 줄이며 이전의 모든 플로트 및 수직 중심 트릭을 대체합니다.

네 가지 Flexbox 패턴

오른쪽으로 밀린 항목이 있는 도구 모음

Flexbox는 어린이를 한 줄로 정렬하고 공간을 공유하는 방법을 결정합니다. 이는 행을 위한 도구입니다. 레이블, 유연한 중간, 고정 값, 수직 중앙에 위치하며 사이에 간격이 있습니다.
Flexbox는 어린이를 한 줄로 정렬하고 공간을 공유하는 방법을 결정합니다. 이는 행을 위한 도구입니다. 레이블, 유연한 중간, 고정 값, 수직 중앙에 위치하며 사이에 간격이 있습니다.
.bar { display: flex; align-items: center; gap: 14px; }
.bar .right { margin-left: auto; }

margin-left: auto는 남은 공간을 모두 흡수하여 해당 항목과 그 뒤의 모든 항목을 오른쪽으로 밀어냅니다. 정확히 두 개의 그룹이 있는 경우에만 작동하는 justify-content: space-between보다 깨끗합니다.

동일한 열

.cols { display: flex; gap: 16px; }
.cols > * { flex: 1; min-width: 0; }

flex: 1는 "성장, 축소, 0부터 시작"의 약어입니다. 따라서 모든 어린이는 내용에 관계없이 동일한 몫을 갖습니다. min-width: 0는 아래에 설명되어 있으며 선택 사항이 아닙니다.

줄어들지 않는 사이드바

.layout { display: flex; gap: 20px; }
.side { flex: 0 0 220px; }   /* never grow, never shrink, 220px */
.main { flex: 1; min-width: 0; }

페이지 수준 레이아웃의 경우 grid-template-columns: 220px 1fr가 포함된 grid는 동일한 내용을 더 직접적으로 나타냅니다.

칩 포장

.chips { display: flex; flex-wrap: wrap; gap: 6px; }

flex-wrap: wrap는 전화기에서 일련의 태그가 넘쳐나는 것을 막는 것입니다. 그것의 부재는 옆으로 스크롤하는 일상적인 원인입니다.

A screenshot of the page ✗ Text is not selectable ✗ Numbers cannot be copied ✗ Charts stop being interactive ✗ Goes stale the moment data changes The live page ✓ Text selects and copies ✓ Tables can be read by tools ✓ Charts still respond to hover ✓ Update the source, link is current
전화기에서 리플로우되는 행을 읽습니다. 아이들이 두루마리를 옆으로 축소하는 것을 거부하는 사람.

축소되는 함정

이것은 사람들에게 오후 비용을 지불하는 것입니다.

플렉스 아이템은 콘텐츠 크기 이하로 줄어들지 않습니다. 따라서 긴 URL, 긴 단어 또는 플렉스 항목 내의 넓은 테이블은 해당 항목을 해당 공유보다 더 넓게 푸시하고 행이 오버플로됩니다.

/* broken: the text refuses to shrink */
.item { flex: 1; }

/* fixed */
.item { flex: 1; min-width: 0; }

잘림도 이에 따라 달라집니다.

.title {
  min-width: 0;              /* without this, nothing below works */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

규칙: 텍스트를 포함하는 모든 플렉스 아이템은 min-width: 0를 얻습니다.

간결하게 정렬

.box {
  display: flex;
  justify-content: center;   /* along the main axis */
  align-items: center;       /* across it */
}
재산 축 공통 가치
justify-content 기본(기본적으로 행) flex-start, center, space-between
align-items 십자가(줄 아래) center, flex-start, stretch, baseline

align-items: baseline는 잘 사용되지 않는 것입니다. 상자가 아닌 기준선에 텍스트를 정렬합니다. 이는 작은 레이블 옆에 큰 숫자가 있을 때 원하는 것입니다.

양방향으로 중심 맞추기:

.center { display: grid; place-items: center; }

그리드는 두 단어로 이를 수행합니다. 그것을 사용하십시오.

Flexbox 또는 그리드

상황 사용
도구 모음, 버튼 행, 칩 행 플렉스박스
카드의 내부 스택 플렉스박스, flex-direction: column
내용이 다양한 동일한 열 둘 중 하나 - 그리드가 덜 까다롭습니다.
리플로우되는 카드 그리드 그리드
페이지 레이아웃 그리드
한 항목이 맨 끝으로 밀렸습니다. margin-left: auto가 포함된 Flexbox

짧은 버전: flexbox는 항목을 한 줄에 따라 배포합니다. 그리드는 컨테이너의 모양을 정의합니다. 컨테이너를 설명하는 경우 그리드를 사용하세요.

잘못된 다섯 가지

증상 원인 수정
텍스트가 해당 항목을 넘칩니다. 항목이 콘텐츠 아래로 줄어들지 않습니다. 항목에 대한 min-width: 0
잘림은 아무 작업도 수행하지 않습니다. 동일 min-width: 0, 그다음에는 text-overflow
칩 한 줄이 넘친다 포장 없음 flex-wrap: wrap
사이드바가 접힙니다. flex: 1도 있습니다 flex: 0 0 220px
가장자리 간격이 고르지 않음 gap 대신 여백 컨테이너의 gap

처음 두 가지는 동일한 원인이며 대부분의 Flexbox 디버깅을 설명합니다. 플렉스 아이템의 기본 최소 크기는 콘텐츠이며, 이는 합리적이며 텍스트에 대해 원하는 크기가 거의 없습니다.

그리드가 더 나은 답인 곳

/* centring, both axes */
.center { display: grid; place-items: center; }

/* a page layout */
.layout { display: grid; grid-template-columns: 220px 1fr; gap: 20px; }

/* cards that reflow with no media query */
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 10px; }

세 가지 모두 Flexbox보다 grid에서 더 짧고 덜 취약합니다. 도구 모음, 버튼 그룹, 카드의 내부 스택 등 항목 행에 대해 Flexbox를 유지하고 컨테이너 모양을 설명할 때 그리드에 접근하세요. 특히 반응형 동작의 경우 자동 맞춤 그리드는 미디어 쿼리 세트를 완전히 대체합니다.

비용이 가장 많이 드는 세 가지 Flexbox 실수

min-width: 0를 잊어버렸습니다. 긴 텍스트가 있는 flex 하위 항목은 텍스트의 자연 너비 아래로 축소되는 것을 거부하므로 행이 전화기에서 오버플로됩니다. 유연한 하위 기능의 min-width: 0를 사용하면 수축하고 감쌀 수 있습니다.

카드 그리드에 flex 사용 flex-wrap는 카드를 래핑하지만 마지막 행은 늘어나서 어색한 간격을 채우거나 남기고 모든 카드에는 너비가 필요합니다. 자동 맞춤 기능이 있는 CSS 그리드는 한 줄로 작업을 수행합니다.

여백을 사용하여 중앙에 배치합니다. align-items: center 및 justify-content: center는 두 줄에서 양방향으로 어린이를 중앙에 배치합니다. 기존 마진 트릭은 더 이상 필요하지 않습니다.

같은 페이지에 있는 Flexbox와 그리드

그들은 경쟁하고 있지 않습니다. 그리드는 페이지 영역과 대시보드의 카드를 설정합니다. Flexbox는 각 카드 내부의 내용을 왼쪽에는 레이블, 오른쪽에는 값, 제목 옆의 아이콘, 행의 버튼으로 정렬합니다.

일반적인 문서에서는 큰 구조에는 그리드를 한두 번 사용하고 작은 행에는 Flexbox를 12번 사용합니다. 올바른 것에 도달하는 것은 대부분 다음과 같은 질문입니다. 이것은 한 줄입니까, 아니면 사물의 표입니까?

Flexbox를 사용하여 행 만들기: 4단계

  1. 행의 상위 항목에 display: flex를 넣습니다. 하위 항목은 기본적으로 가로로 정렬됩니다.
  2. 한 명의 어린이에게 flex: 1를 줍니다. 고정된 너비 뒤에 남은 너비를 모두 사용합니다. 그것은 바 트랙, 검색 상자, 버튼을 오른쪽으로 밀어야 하는 제목입니다.
  3. align-items 및 gap를 사용한 중심 및 공간. 수직 센터링을 위한 align-items: center; gap는 아이들 사이의 공간을 위한 것이며, 끝부분에는 아무것도 두 배로 늘어나지 않습니다.
  4. 좁은 화면에서도 살아남도록 하세요. 긴 텍스트가 줄어들 수 있도록 유연한 하위 항목에서 min-width: 0를 사용하고 전화기에서 행이 두 줄이 되도록 허용하는 경우 flex-wrap: wrap를 사용합니다.

자주 묻는 질문

Flexbox의 용도는 무엇인가요?

도구 모음, 버튼 행, 카드의 내부 스택 등 한 방향으로 항목을 배포합니다. 2차원 레이아웃의 경우 그리드가 더 나은 도구입니다.

한 항목을 오른쪽으로 밀려면 어떻게 해야 합니까?

margin-left: 해당 항목에 자동으로 적용됩니다. 자동 여백은 남은 공간을 모두 흡수하므로 컨테이너의 정렬을 변경하는 것보다 깔끔합니다.

내 텍스트가 플렉스 항목을 넘치게 되는 이유는 무엇입니까?

Flex 항목은 기본적으로 콘텐츠 크기 이하로 줄어들지 않습니다. min-width: 0 항목은 이를 허용하며 텍스트 잘림이 작동하려면 필요합니다.

flex: 1은 무슨 뜻인가요?

성장 1, 축소 1, 기준 0의 약어 - 항목은 내용에 관계없이 동일한 공간을 차지합니다.

함께 읽어 보기