CSS 플렉스박스(flex) flex-grow와 flex-shrink 속성

이재홍·2022년 11월 1일
0
post-thumbnail

플렉스박스의 유연한 레이아웃을 가능하게 하는 가장 중요한 속성 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 속성 적용 방식

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 속성 적용 방식

0개의 댓글