ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Flexbox] flex-grow, flex-shrink, flex-basis(feat. responsible)
    개발/HTML CSS 2022. 8. 9. 16:12

    플렉스를 이용하면 창 크기에 맞게 컨텐츠 크기가 자연스럽게 변하도록

    비교적 간단하게 레이아웃을 만들 수 있습니다.

    미디어 쿼리를 이용하면 반응형 디자인도 어렵지 않게 가능합니다.

     

    일단 플렉스의 기본 동작을 보겠습니다.

    플렉스 아이템을 감싸고 있는 영역을 컨테이너라고 합니다.

    // index.html
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="index.css">
        <title>Document</title>
    </head>
    
    <body>
        <section class="content">
            <div class="flex-container">
                <div class="item">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Incidunt rem quibusdam neque
                    temporibus aut recusandae a repellat placeat. Qui deleniti itaque aut nulla, amet inventore optio
                    praesentium quaerat? Necessitatibus, dolor!</div>
                <div class="item">content2</div>
                <div class="item">content3</div>
                <div class="item">content4</div>
            </div>
        </section>
    </body>
    
    </html>
    
    // index.css
    .content {
        max-width: 50rem;
        margin: 0 auto;
        background-color: rgba(255, 0, 0, 0.2);
        padding: 1rem;
    }
    
    .flex-container {
        display: flex;
        gap: 0.5rem 2%;
    }
    
    .item {
        min-height: 15rem;
        text-align: center;
    }
    
    .item:nth-child(1) {
        background-color: rgb(200, 80, 0);
    }
    
    .item:nth-child(2) {
        background-color: rgb(200, 200, 0);
    }
    
    .item:nth-child(3) {
        background-color: rgb(100, 255, 50);
    }
    
    .item:nth-child(4) {
        background-color: rgb(0, 80, 255);
    }

    너비를 따로 설정해주지 않았지만 컨텐츠에 따라서 동적으로 공간을 채우는 모습입니다.

    창의 너비를 더 좁게 만들어도 플렉스 아이템이 한 줄에 정렬되어 있는 것은 바뀌지 않습니다.

    여기에서 flex-basis라는 속성에 값을 부여하겠습니다.

     

    flex-basis

    flex-basis는 플렉스 아이템의 초기 너비입니다. flex-direction이 row면 width, column이면 height입니다.

    더 자세한 내용은 공식문서를 확인해주세요.

    .item {
        min-height: 15rem;
        flex-basis: 20rem; // or 10rem;
        text-align: center;
    }

    큰 값을 주면 컨테이너를 넘어가지 안 지만 작은 값을 주면 여백이 생깁니다.

    이런 동작이 나오는 이유는 flex-shrinkflex-grow의 기본 값 때문입니다.

     

    flex-grow / flex-shrink

    flex-shrink는 플렉스 아이템의 너비가 플렉스 컨테이너의 너비를 초과할 때의 동작을 제어하는 속성입니다.

    플렉스 아이템의 너비의 총합이 컨테이너보다 커도 컨테이너를 초과하지 않는 이유는 디폴트가 1이기 때문입니다.

    flex-grow는 빈 공간을 할당하는 정도를 정할 수 있는 속성인데 디폴트가 0이므로 빈 공간을 채우지 않은 것입니다.

     

    flex-shrink를 0으로 주고(아이템의 크기가 축소되지 않도록 고정),

    flex-basis의 값을 20rem을 주면 아이템이 컨테이너를 벗어납니다.

    flex-grow를 1로 설정하고 flex-basis의 10rem으로 설정하면

    아이템의 총 너비가 컨테이너보다 작지만 같은 비율로 여백을 채웁니다.

     

    flex-shrink:0 을 하는 이유는 아이템의 크기를 고정하고 싶어서일 텐데,

    그럴 때마다 아이템이 컨테이너를 초과하는 것은 곤란한 일입니다.

    이런 동작이 일어나는 이유는 flex-wrap의 기본 값이 nowrap이기 때문입니다.

    이를 wrap으로 변경해준다면 초과되는 아이템을 자동으로 정렬합니다.

    정렬이 되면서 생기는 빈 공간을 채워야 한다면 flex-grow:1 설정도 필요할 겁니다.

    .flex-container {
        display: flex;
        flex-wrap: wrap;
        gap: 0.5rem 2%;
    }
    
    .item {
        min-height: 15rem;
        flex-basis: 20rem;
        flex-grow: 1;
        flex-shrink: 0;
        text-align: center;
    }

    이러한 특성들을 활용해 반응형 디자인을 위한 간단한 코드를 추가하겠습니다.

     

    responsible web

    flex-basis에는 px, em, rem 말고도 %를 사용할 수 있습니다.

    창의 크기에 따라 동적으로 flex-basis의 크기를 설정하겠습니다.

    반응형이 필요한 이유는 컨텐츠의 크기에 따라 무작위로 레이아웃이 변경되는 걸 막고

    일관된 UX를 유지하기 위해서입니다.

    창이 충분히 클 때는 한 줄에 컨텐츠를 다 보여주고

    창이 특정 크기 이하로 작아지면 정해진 설정대로 컨텐츠를 보여주게 할 수 있습니다.

    flex-basis의 값을 키워주면 아이템이 컨테이너를 초과할 때 초과 아이템을 다음 줄로 내려주는데

    이 때 생기는 빈 공백을 flex-grow:1을 함으로써 채워지게 됩니다.

    .content {
        max-width: 60rem;
        margin: 0 auto;
        background-color: rgba(255, 0, 0, 0.2);
        padding: 1rem;
    }
    
    .flex-container {
        display: flex;
        flex-wrap: wrap;
        gap: 0.5rem 2%;
    }
    
    .item {
        min-height: 15rem;
        /*
        grow shrink basis를 한 번에 표현할 수도 있습니다
        flex: 1 1 20% 
        */
        flex-basis: 20%;
        flex-grow: 1;
        text-align: center;
    }
    
    @media (max-width: 50rem) {
        .item {
            flex-basis: 40%;
        }
    }
    
    @media (max-width: 35rem) {
        .item {
            flex-basis: 100%;
        }
    }
    
    .item:nth-child(1) {
        background-color: rgb(200, 80, 0);
    }
    
    .item:nth-child(2) {
        background-color: rgb(200, 200, 0);
    }
    
    .item:nth-child(3) {
        background-color: rgb(100, 255, 50);
    }
    
    .item:nth-child(4) {
        background-color: rgb(0, 80, 255);
    }

    < 출처 >

    https://developer.mozilla.org/en-US/docs/Web/CSS/flex

    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-basis

    https://blogpack.tistory.com/862

    https://studiomeal.com/archives/197

    댓글

Designed by Tistory.