프로그래밍/HTML·CSS

[CSS] flex-basis, flex-grow, flex-shrink 개념 완벽 정리 & flex 축약법

choar 2021. 11. 28. 01:50
반응형

CSS의 막강한 레이아웃 기능인 Flex!

그중 조금 헷갈리는 flex-basis, flex-grow, flex-shrink 속성의 개념을 완벽히 이해해보도록 하자.

 

 

 

<!DOCTYPE html>
<html>
  <head>
    <title>Flex</title>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div class="container">
      <div class="box">box1</div>
      <div class="box">box2</div>
      <div class="box">box3</div>
      <div class="box">box4</div>
      <div class="box">box5</div>
      <div class="box">box6</div>
    </div>
  </body>
</html>
body {
    box-sizing: border-box;
    font-family: sans-serif;
    font-weight: 600;
}
  
.container {
    display: flex;
    background: #f9f1f0;
    border: 2px solid black;
    width: 90vw;
    height: 200px;
}
  
.box {
    background-color: pink;
    border: 2px solid black;
    width: 100px;
    height: 100px;
    margin: 10px;
    text-align: center;
    line-height: 100px;
}

기본적으로 Flex Container에 display: flex 속성만을 적용한 결과이다.

flex-direction은 기본값인 row로 설정되어 Flex Item들이 좌우로 나열된 것을 볼 수 있다.

flex-basis, flex-grow, flex-shrink는 모두 Flex Item에 사용한다.

 

1. flex-basis 

Flex Item의 크기를 설정한다. 이때 axis 방향으로의 크기를 설정한다.

즉 위의 상태에서 box에 flex-basis 값을 준 경우 box의 좌우 너비가 변하고, flex-direction: column인 경우 높이가 변한다.

이때, flex-shrink 속성을 0으로 설정하지 않는다면 내부 컨텐츠에 따라 유연한 크기를 갖는다.

초기값(default value)은 auto이다.

- Flex Item의 flex-basis가 auto인 경우 width, height 속성이 우선한다.

- Flex Item의 flex-basis가 auto가 아닌 경우, flex-basis 속성이 우선한다.

 

.box:nth-child(1) {
    flex-basis: 200px;
}
.box:nth-child(2) {}

Figure 1

Flex Container가 Axis 방향으로의 크기를 제한하지 않을 경우, flex-basis로 설정한 값(200px)이 Flex Item의 axis 방향 크기(이 경우 width)로 지정된 것을 확인할 수 있다.

(좌) Figure 2 (우) Figure 3

 

Flex Container가 Axis 방향으로의 크기를 제한하게 될 경우, Figure 2, 3과 같이 유연하게 크기가 줄어든다.

 

 

2. flex-grow

Flex Container에 공간이 남을 경우 Flex Item의 flex-basis 크기가 얼마나 더 할당 가능한지 나타내는 속성이다.

초기값(default value)은 0이고, 음수로의 설정은 불가능하다.

 

.box:nth-child(1) {}

.box:nth-child(2) {
    flex-grow: 1;
}

Figure 4

box2 클래스에만 flex-grow: 1; 속성을 준 결과 Flex Container에 axis 방향으로 공간이 남았을 때 box2의 크기가 늘어나서 남은 공간을 차지하게 되었다.

 

.box {
    background-color: pink;
    border: 2px solid black;
    height: 100px;
    margin: 10px;
    text-align: center;
    line-height: 100px;
    flex-grow: 1;
}

.box:nth-child(1) {
    flex-grow: 2;
}
.box:nth-child(2) {}

 

(좌) Figure 5 (우) Figure 6

 

flex-grow는 Figure 5, 6과 같이 Flex Item들이 일정 비율의 크기를 갖게 하고 싶을 때 많이 사용한다.

box1, box2, box3, box4, box5, box6이 2:1:1:1:1:1의 크기 비율을 갖는다.

 

 

3. flex-shrink

flex-grow와 반대로, Flex Container에 공간이 부족해질 때 Flex Item의 axis 방향 크기가 얼마나 줄어들 수 있는지 지정하는 값이다.

초기값(default value)은 1이고, 음수로의 설정은 불가능하다.

 

.box {
    background-color: pink;
    border: 2px solid black;
    height: 100px;
    width: 100px;
    margin: 10px;
    text-align: center;
    line-height: 100px;
}

.box:nth-child(1) {
    flex-basis: 200px;
    flex-shrink: 0;
}

.box:nth-child(2) {}

(좌) Figure 7 (우) Figure 8

box1에만 flex-shrink: 0;을 적용한 결과 Figure 8에서 Flex Container 크기가 줄어도 box1의 크기는 줄어들지 않은 것을 확인할 수 있다.

 

.box {
    background-color: pink;
    border: 2px solid black;
    height: 100px;
    width: 100px;
    margin: 10px;
    text-align: center;
    line-height: 100px;
}

.box:nth-child(1) {
    flex-shrink: 2;
}

.box:nth-child(2) {
    flex-shrink: 3;
}

(좌) Figure 9 (중) Figure 10 (우) Figure 11

모든 Flex Item가 flex-shrink: 1;인데(초기값) box1에 flex-shrink: 2; 및 box2에 flex-shrink: 3;을 주었을 때, Figure 10과 같이 Flex Container의 크기가 줄어들 때 각각의 Item 크기는 2, 3배 빠른 속도로 줄어든다.

크기는 Figure 11과 같이 Item의 content를 변화시키지 않을 때까지만 줄어든다. 왜냐면 디폴트로 min-width: auto, min-height: auto로 설정되어 있기 때문이다.

 

 

Figure 12

최소한으로 줄어들도록 하려면 min-width: 0, min-height: 0, overflow: hidden(visible 빼고 모두 가능) 등으로 설정해주면 Figure 12처럼 content를 무시하고 줄어든다.

 

4. flex

flex-basis, flex-grow, flex-shrink 속성은 flex 속성 단 하나만 이용해서 한줄로 지정할 수 있다.

flex로 한줄로 나타낼 때는 다음과 같은 규칙이 있다.

/* One value, unitless number: flex-grow */
flex: 2;

/* One value, length or percentage: flex-basis */
flex: 10em;
flex: 30%;

/* Two values: flex-grow | flex-basis */
flex: 1 30px;

/* Two values: flex-grow | flex-shrink */
flex: 2 2;

/* Three values: flex-grow | flex-shrink | flex-basis */
flex: 2 2 10%;

(1) 값이 한 개일 때,

- 단위가 없으면 flex-grow 값이 된다.

- 단위가 있으면 flex-basis 값이 된다.

 

(2) 값이 두 개일 때,

- 첫번째 값은 단위가 없는 숫자여야 한다. 또한 첫번째 값은 flex-grow가 된다.

- 두번째 값은 단위가 없으면 flex-shrink, 단위가 있거나 auto면 flex-basis가 된다.

 

(3) 값이 세 개일 때,

- 첫번째 값은 flex-grow, (단위 없어야 함)

- 두번째 값은 flex-shrink, (단위 없어야 함)

- 세번째 값은 flex-basis 값이 된다. (단위 있거나 auto여야 함)

 

 

 

References

https://developer.mozilla.org/ko/docs/Web/CSS/flex-basis

https://developer.mozilla.org/ko/docs/Web/CSS/flex-grow

https://developer.mozilla.org/ko/docs/Web/CSS/flex-shrink

https://developer.mozilla.org/ko/docs/Web/CSS/flex

https://stackoverflow.com/questions/36247140/why-dont-flex-items-shrink-past-content-size

반응형