FrontEnd/css

[css/layout] CSS Layout 방법 - 1️⃣ flexbox

김평범님 2020. 12. 12. 22:20
반응형

💜 2020 State of CSS Survey

2020년 State of CSS Survey 결과가 발표되었다.

개발자의 고충은 내가 만들긴 했는데 이 방법을 써도 되는 걸까?라는 의문을 항상 갖게 된다.

이럴 때 도움이 되는 것은 Survey!

2016년부터 시작된  State of Javascirpt 설문조사가 성공적으로 이뤄짐에 따라

2019년도부터 CSS  Survey도 시작하게 되었다.

 

(결과는 아래 링크를 참조해보자. 오늘도 모르는 게 너무 많은 나를 반성하게 된다.😓)

 

 

The State of CSS 2020

Forget everything you know about CSS. Or at least, be ready to reconsider a lot of it. If like me you've been writing CSS for over a decade, CSS in 2020 looks nothing like what you were used to. Instead of breakpoints, we can now leverage CSS Grid to make

2020.stateofcss.com

 

오늘은 Survey 결과 중  Layout  그중에서도  Flexbox에 집중해보기로 했다.

 


👩‍💻 Flexbox 실무에서는?

전 회사에서는 익스를 반드시 지원해야 하는 환경과

나름  div를 이용한 float:left 형태로도 충분히 내가 원하는 코드를 만들 수 있었기에 사용하지 않았지만

 

이직을 하게 되게 되면서 익스에서 벗어나게 되고 처음  flexbox를 이용했을 때

신세계를 만나게 되었다.

 

 Survey 결과를 보더라도 2019년에도 94.7%를 차지했던 비율이 2020년에는 97.5%를 차지함으로써

많은  css 사용자들이 이젠 즐겨서 사용하는 레이아웃 방식임은 틀림없다.

 

2020 State of CSS Survey Flexbox 결과

 퍼블리셔를 꿈꾸는 주니어들에게 이제  Flexbox는 필수다.

 

단점이 있다면 처음 사용할 때나 익숙하지 않을 때 해당 코드를 읽기가 어렵다는 사실과

해당 기능을 사용하기 위해서는 위에 감싸는 html  element가 불필요하게 필요하다는 사실

 

하지만 기존 float를 이용했을 때 element의 높이 값이 사라져 :after 보정을 하는 귀찮음이 사라진 것과

세로 정렬이 매우 간편해졌다는 사실만으로도 매우 큰 도움이 된다.

 

그럼 지금부터 어떻게 Flexbox를 사용해야 하는지 알아보자. 

 


👧 Flexbox에 대해 알아보기

flexbox  기본구조

우리는 이제 flexbox로 다양한 형태의 레이아웃을 구성해볼 것이다.

flexbox를 사용하기 위해 SampleCode를 만들어보겠다.

 

html 예시

 

<h1>Shopping List</h1>
<div class="container">
	<div>
		<h3>mood light</h3>
		<p>a Christmas present for me</p>
	</div>
	<div>
		<h3>side table</h3>
		<p>To place a book before bedtime</p>
	</div>
	<div>
		<h3>cookie</h3>
		<p>For the Christmas party.</p>
	</div>
</div>

 

flexbox 이용 시 레이아웃을 구성할 element를 감싸는 부모 element가 반드시 필요하다.

위 sample code에서는. container 가 이에 해당하며, 이 영역을 flex 컨테이너라고 부른다.

안에 들어간 div 들은 flex 아이템이라고 부른다.

 

우리는 container 안의 div를 3단 레이아웃 구조로 만들어보도록 하겠다.

 

 CSS 예시

 

 .container { display:flex; }
 
 //디자인을 위한 속성 추가
  .container div {
  padding:10px;
  background:lightblue;
  border-radius: 10px;
  }

 

레이아웃을 구성할 부모  element에  display:flex를  넣어 주면 이제 끝이다.

안에 있는 div들이 이제 밑으로 정렬되는 것이 아닌 옆으로 붙어서 나타나는 걸 확인할 수 있다.

 

결과 화면

.container 밑 div가 옆으로 붙어 3단 레이아웃 완성

 


flex 컨테이너 사용 가능 속성

이제 flex컨테이너에 추가 적인 설정을 이용하여

레이아웃을 여러 형태로 변화해서 사용해보도록 하자.

 

 

 

 

flex-direction

 

나열되는 항목의 속성과 배치 방향을 지정할 수 있습니다.

reverse 속성을 이용할 경우 가장 마지막에 적힌 요소가 앞으로 표시된다.

 

 

flex-direction : column (좌)  / flex-direction: column-reverse; (우)

 

 

flex-direction : row (좌)  /  flex-direction: row-reverse; (우)

 

 

 

 

 

 

justify-content

 

내가 가장 많이 사용하는 기능으로

flex 컨테이너 안의 수평 정렬을 결정해주는 속성이다.

 

  • center :  flex item을 중앙으로 정렬
  • flex-end:  flex item을 끝으로 정렬
  • space-around:  flex item을 중앙으로 정렬하면서 남는 공간은 자동으로 분배하여 띄워주며 양끝도 여분 공간 생성
  • space-between : flex item을 중앙 정렬하면서 남은 공간은 자동으로 분배하되 양끝 여분 공간을 생성하지 않음

 

justify-content :center (좌)  / justify-content :flex-end(우) 

 

justify-content :space-around(좌)  / justify-content :space-between(우) 

 

 

 

 

 

 

align-items

 

flex 컨테이너 안의 수직 정렬을 결정해주는 속성이다.

flex  아이템의 모든 크기가 다를 경우 align-item을 이용하여 세로 정렬 방식을 선택할 수 있다.

 

  • stretch :  높이가 각각 다른 flex item이 있을 경우 item높이는 가장 높은 값을 가진 element에 맞춰 정렬
  • center : item 높이를 유지하되 가장 높은 item을 기준으로 중앙 정렬
  • flex-start : item 높이를 유지하되 위를 기준으로 정렬 
  • flex-end: item 높이를 유지하되 아래를 기준으로 정렬

 

테스트를 위해 가운데 콘텐츠 높이를 다르게 글을 추가했다.

 

align-item :stretch(좌)  / align-item :center(우) 

 

align-item :flex-start(좌)  / align-item :flex-end(우) 

 

 

 

 

 

 

 

flex-wrap

 

flex 속성을 이용하면 flex item들은 모두 옆으로 붙는 형식으로 변경된다.

만약 우리가 3개의 item이 아니라 이 아이템을 늘려서 테스트해보자.

 

item이 많아질 경우 정렬이 필요해보인다. 

 

 

이때 우리는 flex-wrap 속성을 이용하여 한 줄에 적당한 아이템이 표시될 수 있도록 정리할 수 있다.

 

flex-wrap: wrap

 

 


flex item 사용 가능 속성

flex item 에서는 속성 값을 이용해 해당 크기를 지정할 수 있다.

내가 flex 컨테이너에서 얼마만큼의 넓이를 차지할지 말이다!

 

 

 

 

flex-basis

flex item의  넓이를 설정할 수있다. 

예시를 통해 확인해보자.

 

정확한 예시를 확인을 위해 justify-content: space-between;속성을 주었다.

 

.container {
  display:flex;
  justify-content: space-between;
}

 

space-between이 적용된 flex container

 

기본적으로  display:flex를 줄 경우  flex-basis의 기본값은 auto

flex-item의 기본 컨텐츠 크기를 그대로 사용한다.

 

하지만 만약에 flex-basis 특정 크기 값을 지정해주면 flex item은 해당 크기만큼

공간을 차지하게 된다.

 

.container div {flex-basis:100px;}

 

flex-basis:100px (좌) / flex-basis: 250px (우)

 

 

 

 

 

만약 해당 flex-basis가 아닌 flex item에 자체 width가 있을 경우

이때는 flex-basis가 우선 적용된다.

 

.container div {
  padding:10px;
  background:lightblue;
  border-radius: 10px;
  flex-basis: 100px;
}
.container div:nth-child(1) {
  width:250px;
}

첫번째 div width 250px는 무시된다.

 

 

flex-basis를 제외하고 첫 번째 div에만 width를 줄 경우는

해당 width가 적용된 것을 확인할 수 있다.

 

.container div {
  padding:10px;
  background:lightblue;
  border-radius: 10px;
}
.container div:nth-child(1) {
  width:400px;
}

 

첫번째 div width가 적용되었다.

 

 

 

 

 

 

flex-grow

이 속성을 이용할 경우 flexbox에서 남은 여백을 나눠 flex item의 넓이를 자동으로 늘려준다.

이때 값은 남은 여백을 나눌 비율의 숫자 값이 들어간다.

글만으로는 이해가 잘 안 되니 바로 예시를 확인해 보자.

 

 

flex-grow의 기본값은 0이다.

0일 경우는 flex item을 늘리지 않고 원래 width를 사용하지만,

 

flex item에 flex-grow 값을 1을 넣어줄 경우

flex item은 자동으로  flex 컨테이너의 전체 넓이에 맞춰 flex item 넓이를 늘려준다.

 

.container {
  display:flex;
  justify-content: space-between;
}
.container div {
  padding:10px;
  background:lightblue;
  border-radius: 10px;
  margin:5px;
  flex-grow:1;
}

 

flex-grow:1을 적용하니 넓이에 딱맞춰 item 넓이가 자동으로 늘어났다.
flex-grow:0일 경우 기존 컨텐츠 넓이만을 사용한다.

 

 

 

flex-grow에 들어가는 숫자는 넓이의 비율 숫자라고 생각하면 이해가 쉽다.

밑의 예제를 처럼 각 flex item별로 다른 숫자로 flow-grow를 설정해주었다.

 

.container div:nth-child(1) {flex-grow:1;}
.container div:nth-child(2) {flex-grow:3;}
.container div:nth-child(3) {flex-grow:5;}

 

flex-grow 숫자 비율만큼 공간을 차지한다.

 

 

 

 

 

flex-shrink

flex-grow가 여백에 대한 비율이었다면

flex-shrink는 공간이 부족할 경우 넓이를 포기할 비율을 정할 수 있다.

flex-shrink 숫자를 크게 지정할수록 넓이가 빠르게 줄어든다.

 

.container {
  display:flex;
  justify-content: space-between;
}
.container div {
  padding:10px;
  background:lightblue;
  border-radius: 10px;
  margin:5px;
}
.container div:nth-child(1) {
  flex-shrink:1;
}
.container div:nth-child(2) {
  flex-shrink:3;
}
.container div:nth-child(3) {
  flex-shrink:5;
}

 

정상 넓이를 가지고 있을 경우 비율

 

넓이가 줄어 여백값이 없을 경우 줄어든 비율

 

 

 

축약형 속성 flex

flex item에서 해당 속성을 줄 경우, 실무에서는 보통 따로따로 사용하지 않고 축약형으로 사용한다.

설정 순서는 flex-grow, flex-shrink, flex-basis 순으로 작성한다.

 

//flex-grow 비율 1, flex-shrink 비율 1, flex-basis auto를 사용할 경우
.container div {
	flex: 1 1 auto;
}

 

여기까지 따라왔다면 이제 flex의 기본적인 기능은 모두 익혔다.

이제 실무에서 바로 활용해보자.


실무에 바로 이용할 수 있는 Flex Layout


2단 Layout / 3단 Layout

flex로 웹상에서 가장 기본적으로 볼 수 있는 왼쪽 메뉴가 있는 화면 2단 레이아웃 구조를 만들고

메인 컨텐츠에 카드 뉴스가 3단 레이아웃으로 들어가는 형식인  화면을 구성해보았다.

 

2단/3단 Layout 결과화면

<html>

<head>
    <style>
        header {
            width: 100%;
            padding: 10px;
            background: #eee;
            text-align: center;
        }

        .container {
            display: flex;
            width: 100%;
        }

        nav {
            width: 150px;
            text-align: center;
            background: lightgray;
        }

        section {
            flex: 1 1 auto;
            padding: 10px;
        }

        ul.card-news-ul {
            width: 100%;
            margin: 0;
            padding: 0;
            list-style: none;
            display: flex;
            flex-wrap: wrap;
            justify-content: flex-start;
        }

        ul.card-news-ul li {
            flex: 1 1 33.3%;
        }

        ul.card-news-ul li div {
            display: flex;
            align-items: center;
            justify-content: center;
            background: #aaa;
            height: 150px;
            margin: 10px;
            padding: 10px;

        }
    </style>
</head>

<body>
    <header>
        <h1>Header</h1>
    </header>
    <div class="container">
        <nav>
            <h2>nav</h2>
        </nav>
        <section>
            <ul class="card-news-ul">
                <li>
                    <div>card</div>
                </li>
                <li>
                    <div>card</div>
                </li>
                <li>
                    <div>card</div>
                </li>
                <li>
                    <div>card</div>
                </li>
                <li>
                    <div>card</div>
                </li>
                <li>
                    <div>card</div>
                </li>
                <li>
                    <div>card</div>
                </li>
                <li>
                    <div>card</div>
                </li>
                <li>
                    <div>card</div>
                </li>

            </ul>
        </section>
    </div>
</body>

</html>

 

 

아래로 흐르는 List 형식 만들기

보통  float : leftdisplay:inline-block 등의 속성을 이용할 경우,

element들의 순서는 오른쪽에서 왼쪽으로 정렬된다.

 

display:flex를 지정한 뒤 flex-direction:  column 속성과 flex-wrap 속성을 이용하면

숫자가 아래로 흐르다 어느 정도 높이가 지나면 왼쪽으로 흐르는

Ranking 형식 등을 표시할 때 활용할 수 있는 레이아웃을 만들 수 있다.

 

특정 element를 위에서 아래로 정렬하고 싶을 때 활용하면 된다.

 

주의할 점은 flex를 걸어놓은 div에 원하는 정렬이 될 수 있는

height를 반드시 지정해줘야 작동한다.

 

flex를 활용한 아래로 정렬되는 2단 List Layout

<html>

<head>
    <style>
        @import url(https://fonts.googleapis.com/earlyaccess/jejumyeongjo.css);

        * {
            font-family: 'Jeju Myeongjo', serif;
        }

        body {
            width: 50%;
            margin: 0 auto;
        }

        header {
            padding: 10px;
            width: 100%;
            border-bottom: 1px solid #eee;
        }

        .container {
            width: 100%;
        }

        ol.ranking-ul {
            display: flex;
            flex-direction: column;
            height: 200px;
            flex-wrap: wrap;
            justify-content: space-between;
        }

        ol.ranking-ul li {
            margin: 10px;
        }
    </style>
</head>

<body>
    <header>
        <h1>Ranking</h1>
    </header>
    <div class="container">
        <section>
            <ol class="ranking-ul">
                <li>
                    <div>text</div>
                </li>
                <li>
                    <div>text</div>
                </li>
                <li>
                    <div>text</div>
                </li>
                <li>
                    <div>text</div>
                </li>
                <li>
                    <div>text</div>
                </li>
                <li>
                    <div>text</div>
                </li>
                <li>
                    <div>text</div>
                </li>
                <li>
                    <div>text</div>
                </li>
                <li>
                    <div>text</div>
                </li>
                <li>
                    <div>text</div>
                </li>
                </ul>
        </section>
    </div>
</body>

</html>

 

추가적으로 궁금한 레이아웃이 있으면 댓글로 남겨주면 아는 선에서는 답변을 해보도록 하겠다.

 


Reference

developer.mozilla.org/ko/docs/Learn/CSS/CSS_layout/Flexboxdeveloper.mozilla.org/ko/docs/Glossary/Flexbox

 

플렉스박스

플렉스박스(Flexbox)는 요소를 단일 차원(행 또는 열)에 배치하는 레이아웃 모델인 CSS Flexible Box Layout Module을 부를 때 흔히 사용하는 이름입니다.

developer.mozilla.org

 

 

 

반응형