flex-grow flex-shrink 차이, 남는 공간이 1:2로 나뉘는 계산 원리

플렉스 아이템 두 개에 flex-grow: 1과 flex-grow: 2를 나란히 주면, 남는 공간이 신기할 만큼 정확하게 1:2로 갈립니다. 우연이 아니라 브라우저가 정해진 계산식을 그대로 따른 결과입니다.
문제는 flex-basis·flex-grow·flex-shrink 세 값이 이름은 비슷한데 각자 다른 순간에 작동한다는 점입니다. 이 글은 이 세 값이 정확히 무엇을 계산하는지, 숫자를 직접 대입해가며 설명합니다.
요약 ① flex-basis는 grow·shrink 계산이 시작되기 전, 아이템이 원래 가지려는 "기본 크기"입니다. ② flex-grow는 컨테이너에 남는 공간이 있을 때만 작동하며, 그 공간을 grow 값 비율대로 나눠 아이템에 더합니다. ③ flex-shrink는 반대로 공간이 모자랄 때만 작동하며, 부족분을 shrink 값(과 기본 크기)의 비율대로 각 아이템에서 덜어냅니다.
flex-basis — 늘고 줄기 전에 정해지는 "기본 크기"
flex-basis는 flex-grow나 flex-shrink가 계산을 시작하기 전, 아이템이 원래 가지려는 크기입니다. px나 %로 직접 정할 수도 있고, 기본값인 auto를 두면 아이템에 지정된 width(또는 height)나, 그마저 없으면 콘텐츠 크기를 그대로 기본 크기로 씁니다.
여기서 자주 놓치는 부분은 flex-basis가 가리키는 축이 고정돼 있지 않다는 점입니다. flex-direction이 row 계열이면 flex-basis는 너비를 뜻하고, column 계열이면 높이를 뜻합니다. 같은 flex-basis: 100px라도 방향에 따라 실제로 늘어나는 치수가 달라집니다.
실무에서는 flex-basis를 0으로 두는 경우가 특히 많습니다. flex: 1이라는 단축 속성을 쓰면 실제로는 flex-grow: 1; flex-shrink: 1; flex-basis: 0%로 풀립니다. 이 경우 아이템의 원래 크기는 0으로 취급되고, 최종 크기는 전부 grow 계산만으로 정해집니다.
flex-grow — 남는 공간을 비율대로 나눠 갖는 정도
flex-grow는 컨테이너 안에 남는 공간이 있을 때만 작동합니다. 먼저 컨테이너 크기에서 모든 아이템의 flex-basis 합과 gap을 뺀 나머지를 "남는 공간"으로 정합니다. 그다음 이 남는 공간을 각 아이템의 flex-grow 값 비율대로 나눠서, 원래 기본 크기 위에 더해줍니다.
flex-basis가 0인 경우로 계산해 보겠습니다. 컨테이너 너비 900px, gap 0, 두 아이템의 flex-basis가 둘 다 0이라면 남는 공간은 900px 전체입니다. grow 값이 1과 2면 성장 단위 합은 3이므로 단위당 300px(900÷3)이 배분됩니다. 결과는 grow:1 아이템 300px, grow:2 아이템 600px로, 최종 크기 비율도 정확히 1:2가 됩니다.
flex-basis가 0이 아니라면 이야기가 달라집니다. 같은 컨테이너에서 두 아이템의 flex-basis가 각각 100px이라면, 기본 크기 합 200px을 뺀 700px만 남는 공간입니다. 이 700px을 1:2로 나누면 233px과 467px이 추가되고, 최종 크기는 333px과 567px이 됩니다. 비율로 보면 약 1:1.7로, 더 이상 깔끔한 1:2가 아닙니다.
즉 flex-grow의 비율은 "전체 크기"가 아니라 "남는 공간"에만 정확히 적용됩니다. flex-basis가 0일 때만 이 비율이 최종 크기 비율과 그대로 일치합니다.
flex-shrink — 공간이 모자랄 때 비율대로 줄어드는 정도
flex-shrink는 flex-grow와 정반대 상황, 즉 아이템의 기본 크기 합이 컨테이너보다 커서 넘칠 때만 작동합니다. 넘치는 만큼을 각 아이템의 flex-shrink 값과 flex-basis 크기를 곱한 비율대로 나눠서 덜어냅니다.
예를 들어 컨테이너 너비가 300px인데 flex-basis가 150px인 아이템이 세 개 있다면 합이 450px이라 150px이 넘칩니다. shrink 값이 1, 1, 2이고 basis가 모두 150px로 같다면, 줄어드는 양은 shrink 값 비율 그대로 1:1:2가 되어 각각 37.5px, 37.5px, 75px씩 줄어듭니다.
basis가 서로 다르면 계산이 조금 더 복잡해집니다. 실제로는 shrink 값에 flex-basis를 곱한 값끼리 비율을 맞추기 때문에, 같은 shrink 값이라도 원래 크기가 큰 아이템이 더 많이 줄어듭니다. flex-shrink는 "줄어드는 속도"만이 아니라 "원래 크기"까지 함께 반영하는 값입니다.
flex-direction·justify-content·align-items·flex-wrap·gap을 조절하면 미리보기와 복사 가능한 부모 CSS를 바로 보여주는 플렉스박스 생성기

이 도구로 확인할 수 있는 것 — 방향과 줄바꿈이 계산 축을 바꾼다
플렉스박스 생성기는 flex-grow·flex-shrink·flex-basis를 직접 입력하는 도구는 아닙니다. 대신 flex-direction·flex-wrap·justify-content·align-items·gap 같은 부모(컨테이너) 속성을 조절하면서, 지금까지 설명한 계산이 실제로 어떤 조건에서 일어나는지 눈으로 확인할 수 있습니다.
flex-direction을 row에서 column으로 바꿔 보면 "축이 바뀐다"는 설명이 바로 확인됩니다. row일 때는 아이템이 가로로 늘어나고 남는 공간도 가로 방향에서 계산되지만, column으로 바꾸면 같은 아이템들이 세로로 쌓이고 남는 공간도 세로 방향에서 계산됩니다.
flex-wrap도 shrink 계산이 실제로 일어나는지를 가릅니다. wrap을 nowrap으로 두고 아이템 개수를 늘리면, 미리보기 박스들은 기본값인 flex-shrink: 1 때문에 실제로 줄어들다가 지정된 최소 너비 아래로는 더 줄지 못하고 컨테이너가 가로 스크롤로 넘어갑니다. 반대로 wrap으로 두면 줄어드는 대신 다음 줄로 넘어가 버려서, shrink 계산 자체가 일어나지 않습니다.
justify-content와 flex-grow는 남는 공간을 다르게 처리한다
이 도구의 justify-content 옵션(flex-start·center·flex-end·space-between·space-around·space-evenly)은 flex-grow와 자주 헷갈리는 값입니다. 둘 다 "남는 공간"을 다룬다는 점은 같지만 처리 방식이 다릅니다.
justify-content는 아이템 크기를 전혀 바꾸지 않고, 남는 공간을 아이템 사이나 양 끝 여백으로만 배치합니다. 반면 flex-grow는 그 남는 공간을 아이템 자체의 크기로 흡수시킵니다. justify-content를 space-between으로 바꿔보면, 미리보기 박스 크기는 그대로인 채 빈 공간만 사이사이로 옮겨가는 것을 바로 확인할 수 있습니다.
이 도구가 만들어주는 CSS는 부모 컨테이너 몫까지입니다. 여기서 방향과 줄바꿈, 정렬을 먼저 정하고 CSS를 복사한 다음, 자식 요소마다 flex-grow·flex-shrink·flex-basis를 직접 얹으면 지금까지 설명한 계산이 그 위에서 그대로 적용됩니다.
정리
- flex-basis는 grow·shrink 계산 전의 기본 크기이며, flex-direction에 따라 너비 또는 높이 중 무엇을 가리키는지가 달라집니다.
- flex-grow는 남는 공간이 있을 때만 작동하고, 그 공간을 grow 값 비율대로 나눠 아이템에 더합니다. basis가 0이면 최종 크기 비율도 grow 비율과 같아집니다.
- flex-shrink는 공간이 모자랄 때만 작동하고, 부족분을 shrink 값과 basis를 곱한 비율대로 각 아이템에서 뺍니다.
- flex-wrap을 wrap으로 두면 shrink 대신 다음 줄로 넘기는 방식을 택하므로, shrink 계산 자체가 아예 일어나지 않을 수 있습니다.
- justify-content는 아이템 크기를 바꾸지 않고 남는 공간을 아이템 "사이"에 배치하는 것으로, 아이템 자체를 키우는 flex-grow와는 다른 방식의 공간 처리입니다.
flex-direction·justify-content·align-items·flex-wrap·gap을 조절하면 미리보기와 복사 가능한 부모 CSS를 바로 보여주는 플렉스박스 생성기
자주 묻는 질문
flex-grow에 정수가 아니라 소수를 넣어도 되나요?
넣을 수 있습니다. flex-grow는 음수만 아니면 어떤 숫자든 비율 계산에 그대로 쓰입니다. 0.5와 1.5를 나란히 두면 성장 단위 합은 2가 되고, 남는 공간은 1:3 비율로 나뉩니다. 정수로 딱 떨어지지 않아도 계산 방식 자체는 동일합니다.
flex-basis를 auto로 두면 어떤 값이 쓰이나요?
먼저 그 아이템에 width(row 방향일 때) 또는 height(column 방향일 때)가 지정돼 있으면 그 값을 기본 크기로 씁니다. 그마저 없으면 콘텐츠의 실제 크기(글자·이미지가 차지하는 만큼)를 기본 크기로 계산합니다. auto는 "값이 없다"는 뜻이 아니라 "다른 곳에서 크기를 가져온다"는 뜻에 가깝습니다.
flex-shrink를 0으로 설정하면 어떻게 되나요?
그 아이템은 컨테이너가 좁아져도 자신의 flex-basis보다 작아지지 않습니다. 다른 아이템들이 대신 더 많이 줄어들거나, 그래도 공간이 부족하면 컨테이너 밖으로 넘치거나 가로 스크롤이 생깁니다. "절대 줄어들지 않아야 하는 아이템"에 주로 씁니다.
justify-content: space-between을 쓰면 flex-grow는 필요 없나요?
목적이 다릅니다. space-between은 아이템 크기를 그대로 둔 채 남는 공간을 아이템 "사이"로 몰아줍니다. 아이템 자체를 커 보이게 늘리고 싶다면, 즉 빈 여백이 아니라 박스 크기 자체가 커지길 원한다면 여전히 flex-grow가 필요합니다. 두 속성은 같은 남는 공간을 서로 다른 자리에 배치하는 것뿐입니다.
