CSS / Reference / flex-wrap

flex-wrap은 Flex 컨테이너의 아이템을 한 줄에 배치할지, 공간이 부족하면 여러 줄로 나눌지 정하는 CSS 속성입니다. 기본값 nowrap은 한 줄을 유지하며, 아이템이 줄어드는지 넘치는지는 flex-shrink와 최소 크기 등의 조건에 따라 달라집니다. wrap-reverse는 줄이 쌓이는 교차축 방향을 바꾸며 문서의 아이템 순서를 뒤집지는 않습니다.

문법과 세 가지 값

.container {
  display: flex;
  flex-wrap: wrap;
}

이 속성은 아이템이 아니라 부모인 Flex 컨테이너에 지정합니다. display: flex 또는 inline-flex로 Flex 배치를 먼저 활성화해야 합니다. flex-direction이 row이면 주축은 일반적으로 가로 방향이고, column이면 세로 방향입니다. 따라서 줄바꿈 판단을 항상 “가로 너비의 합”으로만 설명할 수는 없습니다.

값 배치와 확인할 점
nowrap 한 줄을 유지합니다. 축소가 허용되면 줄어들 수 있고, 최소 크기나 고정 조건에 막히면 넘칠 수 있습니다.
wrap 아이템이 한 줄에 들어가지 않으면 교차축의 시작 쪽부터 다음 줄을 만듭니다.
wrap-reverse 여러 줄을 만들되 교차축의 시작과 끝을 서로 바꿉니다. 같은 줄 안의 주축 방향은 그대로입니다.

초기값은 nowrap이며 일반적으로 부모의 값을 자동 상속하지 않습니다. initial은 초기값, inherit는 부모의 계산된 값을 명시적으로 받는 전역 키워드입니다. 정확한 정의와 브라우저 지원은 MDN flex-wrap 문서에서 확인할 수 있습니다.

전체 예제: 같은 크기의 다섯 아이템 비교

아래 코드를 flex-wrap.html로 저장하고 브라우저에서 엽니다. 외부 파일은 필요하지 않습니다. 각 아이템은 flex: 0 0 96px로 만들어 늘어나거나 줄어들지 않게 했습니다. 이렇게 해야 줄바꿈 설정만 바꾼 차이를 분명하게 볼 수 있습니다.

<!doctype html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>flex-wrap 세 가지 값 비교</title>
  <style>
    body { margin: 20px; font: 16px/1.6 "Noto Sans KR", sans-serif; color: #203348; }
* { box-sizing: border-box; }
    h1 { font-size: 24px; } h2 { margin: 12px 0 4px; font-size: 18px; }
    .box { display: flex; max-width: 360px; height: 140px; padding: 8px;
      border: 1px solid #7795a3; gap: 8px; align-content: flex-start;
      overflow-x: auto; background: #edf5f7; }
    .item { flex: 0 0 96px; height: 40px; display: grid; place-items: center;
      background: #176f80; color: white; border-radius: 4px; }
    .nowrap { flex-wrap: nowrap; }
    .wrap { flex-wrap: wrap; }
    .reverse { flex-wrap: wrap-reverse; }
    .box:focus-visible { outline: 3px solid #b75c00; outline-offset: 2px; }
  </style>
</head>
<body>
<h1>flex-wrap 비교</h1>
<h2>nowrap</h2>
<div class="box nowrap" tabindex="0" role="region" aria-label="nowrap 예제"><div class="item">가</div><div class="item">나</div><div class="item">다</div><div class="item">라</div><div class="item">마</div></div>
<h2>wrap</h2>
<div class="box wrap"><div class="item">가</div><div class="item">나</div><div class="item">다</div><div class="item">라</div><div class="item">마</div></div>
<h2>wrap-reverse</h2>
<div class="box reverse"><div class="item">가</div><div class="item">나</div><div class="item">다</div><div class="item">라</div><div class="item">마</div></div>
</body>
</html>

컨테이너가 최대 너비 360px일 때 nowrap은 다섯 아이템을 한 줄에 두고 내부 가로 스크롤을 만듭니다. wrap은 가·나·다를 첫 줄, 라·마를 다음 줄에 놓습니다. wrap-reverse에서는 가·나·다 줄이 아래쪽, 라·마 줄이 그 위에 놓입니다. 이 예제의 가로 쓰기·기본 row 방향을 기준으로 설명한 결과이며, 쓰기 방향과 flex-direction이 바뀌면 화면에서 보이는 방향도 달라집니다.

같은 다섯 아이템을 nowrap 한 줄, wrap 두 줄, wrap-reverse 반대 교차축 방향으로 배치한 비교 화면

브라우저 너비를 줄이면 한 줄에 들어가는 개수가 달라집니다. 너비 320px 화면에서는 이 예제의 바깥 여백 때문에 wrap이 두 개·두 개·한 개로 나뉩니다. nowrap 영역은 Tab으로 포커스한 뒤 방향키로 넘친 내용을 확인할 수 있습니다. 스크롤은 해당 컨테이너 내부에만 생기도록 했으므로 페이지 전체가 가로로 밀리지 않는지 함께 확인하세요.

줄바꿈과 flex-shrink는 다른 설정

nowrap을 지정했다고 아이템이 반드시 원래 너비를 유지하는 것은 아닙니다. 일반적인 Flex 아이템은 flex-shrink의 초기값이 1이어서 공간이 부족하면 줄어들 수 있습니다. 반대로 wrap에서도 아이템 하나의 최소 크기가 컨테이너보다 크면 그 아이템은 넘칠 수 있습니다. 줄바꿈은 여러 아이템을 나누는 동작이지 하나의 긴 단어나 큰 이미지를 자동으로 잘라 주는 기능이 아닙니다.

전체 예제의 style 끝에 다음 규칙을 추가해 nowrap만 비교해 보세요. 다섯 아이템이 한 줄을 유지하면서 폭을 나누어 줄어듭니다. 이 규칙을 제거하면 다시 96px를 유지하며 내부 스크롤이 생깁니다.

.nowrap .item {
  flex-shrink: 1;
}

음수 여유 공간은 축소 계수와 기본 크기를 함께 고려해 분배되므로 flex-shrink: 1을 언제나 “모두 같은 픽셀만큼 줄임”으로 이해하면 안 됩니다. 긴 콘텐츠의 자동 최소 크기가 축소를 막을 수도 있습니다. 그때는 필요한 아이템에 min-width: 0을 허용하고 텍스트 줄바꿈·말줄임 방식을 별도로 정하는지 검토하세요. 자세한 계산 조건은 MDN flex-shrink 문서를 참고할 수 있습니다.

아이템의 너비를 퍼센트로 합쳐 100%로 맞춰도 gap이나 바깥 여백이 추가되면 한 줄에 들어가지 않을 수 있습니다. 예를 들어 33.333% 아이템 세 개와 gap 두 개는 컨테이너의 전체 폭을 넘습니다. 필요한 간격을 뺀 기본 크기를 계산하거나, 동일한 열을 유지하려는 목적이라면 Grid의 열 정의가 더 명확한지도 검토하세요.

세로 방향 줄바꿈과 적용되지 않을 때의 점검

column 방향에서는 주축이 세로이므로 제한된 높이가 있어야 그 높이를 기준으로 다음 열을 만들 수 있습니다. 전체 예제에서 wrap 영역에만 아래 규칙을 추가합니다. 기존 flex-basis 96px는 column에서 높이 기준이 되므로, 아이템도 40px 높이 기준으로 함께 바꾸었습니다.

.wrap {
  flex-direction: column;
  height: 150px;
}
.wrap .item {
  flex: 0 0 40px;
  width: 96px;
}

이 조건에서는 한 열에 두 개씩 배치되어 가·나, 다·라, 마의 세 열이 생깁니다. height를 auto로 바꾸면 높이 제한이 사라져 다섯 아이템이 한 열로 이어집니다. 추가한 두 규칙을 제거하면 원래의 가로 wrap 비교로 돌아갑니다. 세로 방향 컨테이너에서 너비만 제한하고 줄바꿈을 기대하거나 아이템 크기의 기준 축을 바꾸지 않는 것이 흔한 혼동입니다.

방향과 줄바꿈을 한 선언으로 정하려면 flex-flow: row wrap처럼 작성할 수 있습니다. flex-flow 단축 속성은 생략한 구성 속성을 초기값으로 되돌리므로, 기존 column 설정을 유지하려면 flex-flow: wrap만 덧붙이지 말고 필요한 방향을 함께 지정하세요.

여러 줄 사이의 배치는 align-content, 각 줄 안에서 주축 방향의 정렬은 justify-content가 담당합니다. 아이템의 읽기 순서나 키보드 이동 순서는 wrap-reverse로 바뀌지 않습니다. 화면 순서가 의미의 순서와 다르면 읽기와 조작이 어려워지므로, 순서를 전달하는 콘텐츠는 먼저 HTML을 논리적인 순서로 작성하세요.