HTML&CSS

CSS 플렉스박스(flex) flex-grow와 flex-shrink 속성의 완벽 이해

apost 2020. 12. 2. 08:55

플렉스박스의 유연한 레이아웃을 가능하게 하는 가장 중요한 속성 2가지가 "flex-grow" 와 "flex-shrink" 입니다.

두 속성은 "flex-basis" 속성으로 정한 플렉스박스 아이템의 기본 너비를 자동으로 늘어나거나(flex-grow) 줄어들도록(flex-shrink) 해서 행 안에 적절한 너비로 배치되도록 맞추는 기능을 합니다.

 

두 속성이 빈 여백, 또는 넘친 아이템 영역을 분배해서 레이아웃 영역 안에 아이템들이 배치되도록 하는 방식에 대해서 알아보겠습니다.

 

 

flex-grow 속성이 남는 행 여백을 분배해서 채우는 방법

flex-grow 속성이 적용되지 않거나, 속성 값이 "0" 인 경우 레이아웃 너비보다 아이템들의 너비 합이 더 작으면 아이템 오른쪽 끝에 여백이 남게 됩니다.

 

 

다음과 같은 기본적인 플렉스박스에서

 

<div class="layout">
    <div class="flexbox">
        <div class="item">content1</div>
        <div class="item">content2</div>
        <div class="item">content3</div>
        <div class="item">content4</div>
    </div>
</div>

 

플렉스박스 아이템 CSS 에서 "flex-grow" 속성을 없애면 다음과 같이 됩니다.

 

.flexbox{
    display: flex;
    flex-wrap: nowrap;
    gap: 0;
    padding: 10px;
    background-color: #e8e8e8;
}
.item{
    min-height: 150px;
    flex-basis: 100px;
}

 

기본 너비가 "100px" 이기 때문에 기본 너비로 고정되면서 너비 "600px" 인 레이아웃 오른쪽에 여백이 남게 됩니다.

 

오른쪽에 여백이 남는 플렉스박스

 

아이템들에 다음처럼 "flex-grow" 속성을 부여하면

.item:nth-child(1){flex-grow: 1;}
.item:nth-child(2){flex-grow: 1;}
.item:nth-child(3){flex-grow: 0;}
.item:nth-child(4){flex-grow: 2;}

 

다음처럼 아이템들이 주어진 비율대로 늘어나면서 레이아웃 영역을 채우게 됩니다.

 

레이아웃에 아이템들이 채워진 플렉스박스

 

영역을 채우는 방식은 다음과 같습니다.

플렉스박스 안의 아이템들에 적용된 "flex-grow" 속성 값의 합을 구합니다. 앞서의 예는 4가 됩니다.

플렉스박스의 남는 여백을 4로 나눕니다. 남는 공간의 여백은 "180px" 이고 180px / 4 = 45px 가 됩니다. 실제 아이템이 차지하는 영역을 기준으로 하기 때문에 패딩 영역이 차지하는 20px는 제외됩니다.

"flex-grow" 속성 값을 기준으로 비율 만큼씩 아이템 너비를 더합니다.

원래의 너비였던 "100px" 에서 왼쪽 아이템부터 순서대로 45px, 45px, 0px, 90px 를 더하면 최종 너비가 됩니다.

 

플렉스박스 "flex-grow" 속성의 적용 방식을 정리하면 다음과 같습니다.

 

flex-grow 속성 적용 방식

 

 

 

 

flow-shrink 속성이 레이아웃을 벗어난 아이템 너비를 분배해서 줄이는 방법

flex-shrink 속성은 플렉스박스에 "flex-wrap: wrap;" 속성을 부여한 경우 적용되지 않습니다.

"flex-wrap" 속성을 정의하지 않거나(기본 값 "nowrap") "flex-wrap: nowrap;" 속성을 부여해야 합니다.

레이아웃 너비를 넘을 경우 끝에 걸치는 아이템은 다음 행의 왼쪽부터 다시 배치되기 때문에 레이아웃 영역을 넘는 상황이 생기지 않습니다.

 

그리고 "flex-shrink" 속성은 기본 값이 "1"이기 때문에 속성을 정의하지 않아도 자동으로 아이템이 축소되어 적용된다는 것을 염두해야 합니다.

자동으로 아이템 너비가 축소되지 않도록 하려면 반드시 "flex-shrink: 0;"을 아이템에 선언해야 합니다.

 

아이템들의 너비 합이 레이아웃 너비보다 넓은 다음 예를 사용해 레아웃을 넘어간 아이템 영역을 분배해서 줄이는 원리를 알아보겠습니다.

 

<div class="layout">
    <div class="flexbox">
        <div class="item">content1</div>
        <div class="item">content2</div>
        <div class="item">content3</div>
        <div class="item">content4</div>
    </div>
</div>

 

플렉스박슨 너비는 "600px" 이고 아이템 너비는 "200px" 입니다. "flex-shrink: 0;" 속성을 아이템에 부여해 아이템 자동 축소를 강제로 막았습니다.

 

.layout{
    max-width: 600px;
    margin: 0 auto;
    padding: 0;
}
.flexbox{
    display: flex;
    flex-wrap: nowrap;
    gap: 0;
    padding: 10px;
    background-color: #f0f0f0;
}
.item{
    min-height: 150px;
    flex-basis: 200px;
    flex-shrink: 0;
}

 

레이아웃 영역을 넘어선 아이템들

 

아이템들에 "flex-shrink: 1;" 속성을 부여하면 아이템들 너비가 똑같이 줄어들어 다음처럼 아이템 너비가 모두 "145px" 가 됩니다.( 145px x 4 = 580px + 플렉스박스 패딩 10px x 2 = 600px)

아이템들에 "flex-shrink" 속성을 다음처럼 각각 부여해서 남는 아이템 너비가 어떻게 분배 축소되는지 확인해보겠습니다.

 

.item:nth-child(1){flex-shrink: 1;}
.item:nth-child(2){flex-shrink: 0;}
.item:nth-child(3){flex-shrink: 1;}
.item:nth-child(4){flex-shrink: 2;}

 

아이템들의 "flex-shrink" 속성 값의 합은 4입니다. 그리고 아이템이 플렉스박스에서 넘어간 너비는 "220px" 입니다.(패딩 공간도 넘어간 것 영역에 포함됩니다.)

220px / 4 = 55px 가 되고 "55px" 가 "flex-shrink" 속성 값 1의 너비가 됩니다.

이제 속성 값 만큼씩 너비를 맞춰서 줄이면 다음처럼 아이템 영역이 정해집니다.

각각의 너비는 순서대로 145px, 200px, 145px, 90px 가 됩니다.

 

축소 비율에 맞춰 너비가 줄어든 아이템들

 

 

플렉스박스 "flex-shrink" 속성의 적용 방식을 정리하면 다음과 같습니다.

 

flex-shrink 속성 적용 방식