개발 공부 기록하기

DAY 33. 플렉스 박스 레이아웃(Flex Box Layout) 본문

프밍/CSS

DAY 33. 플렉스 박스 레이아웃(Flex Box Layout)

태영(泰伶) 2023. 1. 24. 15:07

(반응형 웹 디자인에 적합한) 그리드 레이아웃grid layout을 만드는 방법 中

             ⤻

                                수식

 

첫 번째, 플렉스 박스 레이아웃flexible box layout.

 

낯선 용어들 먼저 정리하고 가자.

flex container
플렉스 컨테이너, 부모 박스
flex item들을 모두 묶은 요소.  
flex item
플렉스 항목, 자식 박스
flex box를 구성하는 요소들 모두.
위 동영상에서는 1번 ~ 6번 박스들을 의미.
 
main axis
주축
flex box의 주된 배치 방향.
늘 수평방향을 의미하지는 않음.
위 동영상에서 1번 박스 왼쪽 위 꼭짓점을 '주축 시작점', 2번 박스 오른쪽 위 꼭짓점을 '주축 끝점'이라고 칭함.
cross axis
교차축
flex box의 주축과 교차하는 방향.
늘 수직방향을 의미하지는 않음.
위 동영상에서 1번 박스 왼쪽 위 꼭짓점을 '교차축 시작점', 4번 박스 왼쪽 아래 꼭짓점을 '교차축 끝점'이라고 칭함.

 

 

1. flex container의 범위를 지정하자, display

특정 요소가 flex container로 동작하도록 하려면 display 속성을 이용해야 한다.

display: flex; flex item을 블록 레벨 요소로 배치.
display: inline-flex; flex item을 인라인 레벨 요소로 배치.

 

 

 

 

 

2. flex item 배치 방향을 지정하자, flex-direction

main axis가 수평 방향(가로)이냐, 아님 수직 방향(세로)이냐,

그리고 배치 순서는 어디서 어디냐 지정하는 속성이다.

  main axis는 어디? 배치 순서는? 비고
flex-direction: row; 가로 왼 → 오 default값.
flex-direction: row-reverse; 가로 오 → 왼  
flex-direction: column; 세로 위 → 아래  
flex-direction: column-reverse; 세로 아래 → 위  

 

예제 1.

<!-- 깨알 복습 time - Emmet -->
<!-- 편의상 다른 상용구는 생략함! -->
<body>
   .container#opt$*4>.box*3>p{$}
</body>
<!-- 흐흐 의도한대로 성공!!♬ -->
<!DOCTYPE html>
   <html lang="ko">
      <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">
         <title>Flex box layout</title>
         <style>
            .container {
               width: 700px;
               display: flex;				/* flax container 지정 */
               background-color: #eee;
               border: 1px solid #e5529c;
               margin-bottom: 30px;
            }
            
            .box {
               padding: 5px 45px;			/* 상하 padding 5px, 좌우 padding 45px */
               margin: 5px;
               width: 80px;
               background-color: #e5529c;
            }

            #opt1 {
               flex-direction: row;			/* main-axis: 가로, 방향: 왼 → 오 */
            }

            #opt2 {
               flex-direction: row-reverse;		/* main-axis: 가로, 방향: 오 → 왼 */
            }

            #opt3 {
               flex-direction: column;			/* main-axis: 세로, 방향: 위 → 아래 */
            }

            #opt4 {
               flex-direction: column-reverse;		/* main-axis: 세로, 방향: 아래 → 위 */
            }

            p {
               color: #fff;
               text-align: center;
            }
         </style>
      </head>
      <body>
         <div class="container" id="opt1">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
         </div>
         <div class="container" id="opt2">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
         </div>
         <div class="container" id="opt3">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
         </div>
         <div class="container" id="opt4">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
         </div>
      </body>
   </html>

위에서부터 순서대로 row, row-reverse, column, column-reverse.

 

 

 

 

 

3. flex item 줄 바꿈 하자, flex-wrap

  설명 비고
flex-wrap: nowrap; flex item 한 줄에 표시. default값.
flex-wrap: wrap; flex item 여러 줄에 표시.  
flex-wrap: wrap-reverse; flex item 여러 줄에 표시 & 시작점, 끝점 바뀜.  

 

예제 2.

<!-- 상용구 다 생략 -->
<!-- Emmet 사용해서 예제 간단 입력하기 -->
<body>
   .container#opt$*3>.box*6>p{$}
</body>
<!DOCTYPE html>
   <html lang="ko">
      <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">
         <title>Flex box layout</title>
         <style>
            .container {
               display: flex;			/* flex container 지정 */
               background-color: #eee;
               border: 1px solid #e5529c;
               margin-bottom: 30px;
            }
            
            .box {
               padding: 5px 45px;		/* 상하 padding 5px, 좌우 padding 45px */
               margin: 5px;
               width: 80px;
               background-color: #e5529c;
            }

            #opt1 {
               flex-wrap: nowrap;		/* flex item을 한 줄에 표시 */
            }

            #opt2 {
               flex-wrap: wrap;			/* flex item을 여러 줄에 표시 */
            }

            #opt3 {
               flex-wrap: wrap-reverse;		/* flex item을 여러 줄에 표시 & 시작점, 끝점 바뀜 */
            }

            p {
               color: #fff;
               text-align: center;
            }
         </style>
      </head>
      <body>
         <div class="container" id="opt1">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
            <div class="box"><p>5</p></div>
            <div class="box"><p>6</p></div>
         </div>
         <div class="container" id="opt2">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
            <div class="box"><p>5</p></div>
            <div class="box"><p>6</p></div>
         </div>
         <div class="container" id="opt3">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
            <div class="box"><p>5</p></div>
            <div class="box"><p>6</p></div>
         </div>
      </body>
   </html>

위에서부터 순서대로 nowrap, wrap, wrap-reverse.

 

 

 

 

 

4. flex item 배치 방향과 줄 바꿈을 동시에 지정하자, flex-flow

위에서 다룬 flex-direction과 flex-wrap을 한꺼번에 작성하는 속성.

flex item의 배치 방향을 결정하고 줄을 바꾼다.

flex-flow: row nowrap;		/* ← 이게 기본값(default). */

 

예제 3.

<!DOCTYPE html>
   <html lang="ko">
      <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">
         <title>Flex box layout</title>
         <style>
            .container {
               display: flex;			/* flex container 지정 */
               background-color: #eee;
               border: 1px solid #e5529c;
               margin-bottom: 10px;
            }

            #opt1 {
               flex-flow: row wrap;		/* 왼 → 오, 여러 줄 */
            }

            #opt2 {
               flex-flow: row nowrap;		/* 왼 → 오, 한 줄 */
            }

            .box {
               padding: 5px 45px;		/* 상하 padding 5px, 좌우 padding 45px */
               margin: 5px;
               background-color: #e5529c;
            }

            p {
               color: #fff;
               text-align: center;
            }
         </style>
      </head>
      <body>
         <div class="container" id="opt1">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
            <div class="box"><p>5</p></div>
            <div class="box"><p>6</p></div>
         </div>
         <div class="container" id="opt2">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
            <div class="box"><p>5</p></div>
            <div class="box"><p>6</p></div>
         </div>
      </body>
   </html>

위의 것은 row wrap, 아래 것은 row nowrap.

 

 

 

 

 

5. main axis 방향으로 flex item 정렬할 땐? justify-content

justify-content: flex-start; main axis 시작점에 맞춰서 배치.
justify-content: flex-end; main axis 끝점에 맞춰서 배치.
justify-content: center; main axis 중앙에 배치.
justify-content: space-between; main axis 시작점, 끝점에 flex item 첫 번째 것, 마지막 것 배치하고
나머진 그 사이에 같은 간격으로 배치.
justify-content: space-around; 모든 flex item을 main axis에 같은 간격으로 배치.

 

예제 4.

<!-- 다른 상용구는 생략 -->
<!-- Emmet으로 예제 간단 입력하기 -->
<body>
   .container#opt$*5>.box*4>p{$}
</body>
<!DOCTYPE html>
   <html lang="ko">
      <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">
         <title>Flex box layout</title>
         <style>
            .container {
               display: flex;				/* flex container 지정 */
               background-color: #eee;
               border: 1px solid #e5529c;
               margin-bottom: 10px;
            }

            #opt1 {
               justify-content: flex-start;		/* main axis 시작점 기준으로 배치 */
            }

            #opt2 {
               justify-content: flex-end;		/* main axis 끝점 기준으로 배치 */
            }

            #opt3 {
               justify-content: center;			/* main axis 중앙으로 배치 */
            }

            #opt4 {
               justify-content: space-between;		/* main axis 시작점, 끝점 배치 후 나머진 같은 간격으로 배치 */
            }

            #opt5 {
               justify-content: space-around;		/* flex item 전체를 같은 간격으로 배치 */
            }

            .box {
               padding: 5px 45px;			/* 상하 padding 5px, 좌우 padding 45px */
               margin: 5px;
               background-color: #e5529c;
            }

            p {
               color: #fff;
               text-align: center;
            }
         </style>
      </head>
      <body>
         <div class="container" id="opt1">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
         </div>
         <div class="container" id="opt2">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
         </div>
         <div class="container" id="opt3">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
         </div>
         <div class="container" id="opt4">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
         </div>
         <div class="container" id="opt5">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
         </div>
      </body>
   </html>

위에서부터 순서대로 flex-start, flex-end, center, space-between, space-around.

 

 

 

 

 

6. cross axis 방향으로 한 줄짜리 flex item을 정렬할 땐? align-items

align-items: flex-start; cross axis 시작점에 맞춰서 배치.
align-items: flex-end; cross axis 끝점에 맞춰서 배치.
align-items: center; cross axis 중앙에 배치.
align-items: baseline; cross axis 문자 기준선에 맞춰서 배치.
align-items: stretch; flex item을 쭉 늘려서 cross axis에 가득 차게 배치.

 

예제 5.

<!DOCTYPE html>
   <html lang="ko">
      <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">
         <title>Flex box layout</title>
         <style>
            .container {
               width: 100%;
               height: 150px;
               display: flex;			/* flex container 지정 */
               background-color: #eee;
               border: 1px solid #e5529c;
               margin-bottom: 20px;
            }

            #opt1 {
               align-items: flex-start;		/* cross axis 시작점 기준으로 배치 */
            }

            #opt2 {
               align-items: flex-end;		/* cross axis 끝점 기준으로 배치 */
            }

            #opt3 {
               align-items: center;		/* cross axis 중앙으로 배치 */
            }

            #opt4 {
               align-items: baseline;		/* 문자 기준선에 맞춰 배치 */
            }

            #opt5 {
               align-items: stretch;		/* flex item를 늘려서 교차축에 가득차게 배치 */
            }

            .box {
               padding: 5px 45px;		/* 상하 padding 5px, 좌우 padding 45px */
               margin: 5px;
               background-color: #e5529c;
            }

            p {
               color: #fff;
               text-align: center;
            }
         </style>
      </head>
      <body>
         <div class="container" id="opt1">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
         </div>
         <div class="container" id="opt2">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
         </div>
         <div class="container" id="opt3">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
         </div>
         <div class="container" id="opt4">
         /* 책 속 예제에는 특정 px의 글자 크기를 채택했지만, 직관적 비교를 위해 임의로 %로 글자 크기를 바꾸었다. */
            <div class="box"><p>1</p></div>
            <div class="box"><p style="font-size: 50%;">2</p></div>
            <div class="box"><p style="font-size: 200%;">3</p></div>
            <div class="box"><p style="font-size: 10%;">4</p></div>
         </div>
         <div class="container" id="opt5">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
         </div>
      </body>
   </html>

위에서부터 flex-start, flex-end, center, baseline, stretch. 교차축(cross axis) 기준이라면서 왜 가로로 정렬된 것처럼 보이느냐면, flex-direction을 별도로 지정하지 않아도 row로 기본적으로 설정되어 있기 때문!!

 

 

 

 

 

7. cross axis 방향으로 여러 줄짜리 flex item을 정렬할 땐? align-content

align-content: flex-start; cross axis 시작점에 맞춰서 배치.
align-content: flex-end; cross axis 끝점에 맞춰서 배치.
align-content: center; cross axis 중앙에 배치.
align-content: space-between; cross axis 시작점, 끝점에 flex item 첫 번째 것, 마지막 것 배치하고
나머진 그 사이에 같은 간격으로 배치.
align-content: space-around; 모든 flex item을 cross axis에 같은 간격으로 배치.
align-content: stretch; flex item을 쭉 늘려서 cross axis에 가득 차게 배치.

 

예제 6.

<!-- 다른 상용구 생략 -->
<!-- Emmet으로 예제 입력하기 -->
<body>
   .container#opt$*6>.box*4>p{$}
</body>
<!DOCTYPE html>
   <html lang="ko">
      <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">
         <title>Flex box layout</title>
         <style>
            .container {
               float: left;
               width: 200px;
               height: 150px;
               display: flex;			/* flex container 지정 */
               flex-flow: row wrap;		/* 왼 → 오, 여러 줄 */
               background-color: #eee;
               border: 1px solid #e5529c;
               margin: 30px;
            }

            #opt1 {
               align-content: flex-start;		/* cross axis 시작점 기준 */
            }

            #opt2 {
               align-content: flex-end;			/* cross axis 끝점 기준 */
            }

            #opt3 {
               align-content: center;			/* cross axis 중앙 기준 */
            }

            #opt4 {
               align-content: space-between;		/* cross axis 시작점, 끝점 배치 후 나머지는 중간에 같은 간격으로 배치 */
            }

            #opt5 {
               align-content: space-around;		/* 모든 flex item을 같은 간격으로 배치 */
            }

            #opt6 {
               align-content: stretch;			/* flex item을 쭉 늘려 cross axis에 가득 차게 배치 */
            }

            .box {
               width: 80px;
               background-color: #e5529c;
               border: 1px dotted #e9e9e9;
            }

            p {
               color: #fff;
               text-align: center;
            }
         </style>
      </head>
      <body>
         <div class="container" id="opt1">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
         </div>
         <div class="container" id="opt2">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
         </div>
         <div class="container" id="opt3">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
         </div>
         <div class="container" id="opt4">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
         </div>
         <div class="container" id="opt5">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
         </div>
         <div class="container" id="opt6">
            <div class="box"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box"><p>3</p></div>
            <div class="box"><p>4</p></div>
         </div>
      </body>
   </html>

검은색 글씨는 ppt로 삽입해 넣은 것임. 코드로는 안 나타나는 게 정상!!

 

 

 

 

 

8. 특정 flex item만 정렬하고 싶을 땐? align-self

align-items은 flex container가 되는 선택자에 쓰는 속성이지만,

그에 비해 align-self는 flex item이 되는 선택자에 쓰는 속성이다.

 

그로써 각각의 flex item 정렬 방법을 개별적으로 지정할 수 있다.

(속성값은 align-items에서와 동일하다..!)

 

예제 7.

<!-- Emmet 이용해서 예제 따라쓰기ㅎㅎ -->
<!-- 편의상 다른 상용구 생략 -->
<body>
   .container>(.box#box1>p{1})+(.box>p{2})+(.box#box3>p{3})+(.box>p{4})
</body>
<!DOCTYPE html>
   <html lang="ko">
      <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">
         <title>Flex box layout</title>
         <style>
            .container {
               width: 450px;
               height: 150px;
               background-color: #eee;
               border: 1px solid #e5529c;
               margin-bottom: 20px;
               display: flex;			/* flex container 지정 */
               align-items: center;		/* flex container가 되는 선택자에서 쓰는 속성!! + cross axis 중앙에 배치!*/
            }

            .box {
               padding: 5px 45px;		/* 상하 padding 5px, 좌우 padding 45px */
               margin: 5px;
               background-color: #e5529c;
            }

            #box1 {
               align-self: flex-start;		/* flex item이 되는 선택자에서 쓰는 속성!! + cross axis 시작점에 배치 */
            }

            #box3 {
               align-self: stretch;		/* flex item이 되는 선택자에서 쓰는 속성!! + cross-axis에 가득 차게 늘림 */
            }

            p {
               color: #fff;
               text-align: center;
            }
         </style>
      </head>
      <body>
         <div class="container">
            <div class="box" id="box1"><p>1</p></div>
            <div class="box"><p>2</p></div>
            <div class="box" id="box3"><p>3</p></div>
            <div class="box"><p>4</p></div>
         </div>
      </body>
   </html>

1번 box가 flex-start, 3번 box는 stretch. 2번과 4번에는 아무 처치(?) 안 함.

 

 

 

 

 

9. 아, 다 됐고, 무조건 중앙 정렬 가즈아!

예제 8.

<!DOCTYPE html>
   <html lang="ko">
      <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">
         <title>세로로 중앙에 배치하기</title>
         <style>
            * {
               margin: 0;
               box-sizing: border-box;
            }
            
            body {
               background: url('images/bg5.jpg') no-repeat left top fixed;
               background-size: cover;
               display: flex;
               justify-content: center;
               align-items: center;
               min-height: 100vh;
            }

            button {
               background-color: #ccc;
               font-size: 1.2em;
               padding: 1em 2em;
               border: none;
               border-radius: 5px;
               box-shadow: 1px 1px 2px #fff;
            }
         </style>
      </head>
      <body>
         <button>클릭!</button>
      </body>
   </html>

Comments