Flex

kirin.log·2020년 11월 16일
3

Flex

👉 display:flex 문법을 적용하면 기본적으로 가로정렬(수평정렬)로 설정됨.
👉 container와 1개 이상의 items로 구성되어야함 (부모-자식 관계로 구성되어야 한다)
👉 container 자체는 block 타입이 유지되어 화면의 전체 너비를 차지.

기본 구성

<style>
   .container{
       background-color: powderblue;
       display: flex;
      /* display: inline-flex; */
   }
   .item{
       background-color: tomato;
       color: white;
       border: 1px solid white;
   }
</style>
<body>   
  /* 부모-자식 관계로 이루어져 있어야 flex가 가능(꼭 container-item일 필요 없음) */
   <div class="container">
       <div class="item">1</div>
       <div class="item">2</div>
       <div class="item">3</div>
       <div class="item">4</div>
       <div class="item">5</div>
   </div>
</body>
<!--display:flex; 를 적용한 결과, item들이 수평정렬이 되었다.(row, 왼쪽이 기준)-->

display: flex;display: inline-flex; 의 차이
display: inline-flex;의 경우, 컨테이너가 아이템 너비만큼만 차지하게 되고, 화면의 전체 너비가 차기 전까지는 컨테이너가 화면에 나란히 나타난다.

부모(container)와 자식(items)에 각각 적용되는 속성

부모(container)에 들어가는 속성과 자식(items)에 들어가는 속성이 구분되어 있다.

부모(container)에 적용되는 속성

👉 display:flex 속성

.container {
    display: flex;         /* flex를 사용하겠다고 선언 */
    flex-direction: row;   /* 메인축(main-axis)을 수평으로 하겠다고 선언(왼-오) */
    flex-wrap: wrap;     /* 한 줄에 들어있는 item들을 한 줄에 넣겠다고 선언(줄바꿈X) */
 /* flex-wrap: nowrap; -> item이 한 줄에 다 차면 다음 줄로 자동 넘어감 */
}

👉 flex-direction 속성

row; / row-reverse; / column; / column-reverse;

---flex-direction 적용한 예시(1)---
   .container{
       background-color: powderblue;
       display: flex;
       flex-direction: row-reverse;  
       /* row(가로)를 바꾸다(reverse). flex의 기준 방향을 row(가로)의 역방향으로 한다 
          -> 각 item들(inline)이 수평방향(오른쪽 시작)으로 놓인다 */
   }
   .item{
       background-color: tomato;
       color: white;
       border: 1px solid white;
   }

---flex-direction 적용한 예시(2)---
   .container{
       background-color: powderblue;
       display: flex;
       flex-direction: column;  
       /* flex의 기준 방향을 column(세로)로 한다 
          -> 각 item들(inline)이 수직방향(윗쪽이 시작)으로 놓인다 */
   }
   .item{
       background-color: tomato;
       color: white;
       border: 1px solid white;
   }

👉 flex-wrap; 속성

브라우저 사이즈가 줄었을 때 행에 맞지 않으면 아이템 사이즈를 줄이는 게 아니라 다음 라인으로 넘기고 싶을 수도 있다. 이럴 때 flex-wrap 속성으로 컨테이너에 직접 선언하면 된다.

.container {
     display: inline-flex;
     flex-wrap: wrap;
     width: 250px;
}
.item {
     width: 100px;
     height: 100px;
}

컨테이너의 너비가 250px이기 때문에 만약 각 아이템 너비가 100px이라면, 아이템 개수가 3개 이상이 되면 다음 줄로 넘어가서 나타나게 된다.

🔶 flex-wrap 옵션 3개
wrap 너비를 넘어가게 되면 다음줄로 이동
wrap-reverse wrap에서 순서 바뀜
nowrap 줄넘김 없음(한줄에 다 넣기)

👉 justify-content; 속성

부모 컨테이너의 display 속성 값을 flex 또는 inline-flex로 변경하면 모든 하위 요소(flex item)들은 부모 컨테이너의 왼쪽 상단으로 이동한다. (왼쪽 상단이 기본 값이다.)
그래서 만약 flex item들이 정렬되는 옵션을 바꾸고 싶으면 justify-content 속성 값을 조정하면 된다.

.container {
     display: flex;
     flex-flow: row nowrap;        //메인축을 수평기본으로 지정(row)
     justify-content: flex-start;  //수평축을 기준으로 item의 start는 왼쪽에서 오른쪽(기본)
     /* justify-content: flex-start; 는 수평축을 기준으로 item이 end에서 시작하므로 오른쪽에서 왼쪽으로 정렬된다 */ 
     /* item들의 순서는 유지하되, 시작하는 순서가 star이면 왼쪽(수평정렬일때), end이면 오른쪽(수평정렬일때) */
}

🔶 justify-content 옵션 5개
flex-start
왼쪽부터 순서대로 배치됨(row기준). 아이템 사이 여백 없음.
위쪽부터 순서대로 배치됨(column기준). 아이템 사이 여백 없음.
flex-end
오른쪽에 붙어서 정렬(row기준). 아이템 사이 여백 없음.
아래쪽부터 순서대로 배치됨(column기준). 아이템 사이 여백 없음.
center
가운데 정렬. 아이템 사이 여백 없음.
space-around
동일한 간격으로 배치. 아이템 사이 여백이 생김.(item하나당 양쪽에 space 적용
-> 첫번째 item의 왼쪽보다 1~2번째 item 사이의 space가 더 넓음(2개의 item의 space를 합쳤기 때문)
space-between
동일한 간격으로 배치. 아이템 사이 여백 있으나 첫 번째 요소 앞, 마지막 요소 뒤에는 여백 없음. (첫번째와 마지막 item은 양쪽 끝에 붙이고, item들 사이에만 space 적용)
space-evenly
균일한 간격 배치.

👉 align-items; 속성

콘텐츠 높이가 다를 때 세로로 어떻게 정렬할 것인지 정하는 align-items 속성.

.container {
     align-items: baseline;
}

🔶 align-items 옵션 5개
flex-start 부모 컨테이너 위쪽 정렬.
flex-end 부모 컨테이너 아래쪽 정렬.
center 부모 컨테이너 가운데 정렬.
baseline 가장 큰 아이템을 기준으로 나머지 아이템들을 균등하게 정렬.
(가장 크기가 큰 아이템이 부모 컨테이너 시작점이 됨.)

stretch 부모 컨테이너 꽉 차게 위 아래로 펼쳐서 맞춤 정렬. 이게 기본 값.
(만약 요소의 height가 정해져 있다면 펼쳐지지 않으나, min-height 만 지정되어 있거나 height가 따로 명시 안 되어 있다면 펼쳐짐.)

자식(items)에 적용되는 속성

grow & shrink 속성

container의 크기(size)가 바뀌었을 때, (--화면의 크기가 늘어나거나 줄어들었을 때--)
item들이 얼마나, 어떻게 늘어나고 줄어들어야 하는지 정의.

---grow---
.item1{
     width: 30px;
     height: 30px;
     flex-grow:1;  
 }
.item2{
     width: 30px;
     height: 30px;
     flex-grow:1;  
 }
 .item3{
     width: 30px;
     height: 30px;
     flex-grow:2;   
 /* item 1,2가 1의 비율 grow를 갖고 있는것에 비해 2의 비율을 갖고 있으므로
     화면이 늘어나면 1:1:2의 비율로 item들이 늘어난다(item3은 2배로 늘어남) */
---shrink---
.item1{
     width: 30px;
     height: 30px;
     flex-shrink:1;  
 }
.item2{
     width: 30px;
     height: 30px;
     flex-shrink:1;  
 }
 .item3{
     width: 30px;
     height: 30px;
     flex-shrink:2;   
/* item 1,2가 1의 비율 shrink를 갖고 있는것에 비해 2의 비율을 갖고 있으므로 
    화면이 줄어들면 1:1:2의 비율로 item3이 가장 줄어든다 */
 }

🟣 flex-basis: (n)px; 속성

항목의 크기를 결정한다 (기본값: flex-basis: auto;)

.container {
  display: flex;         
  flex-direction: row;   
  flex-wrap: nowrap;     // 한 줄에 들어있는 item들을 한 줄에 넣겠다고 선언(줄바꿈X) 
 /* flex-flow: row, nowrap; -> flex의 속성들을 한 줄에 써줄 수 있다 */
}
.item {
    flex-basis: auto; /* 기본값 */
    /* flex-basis: 0; */
    /* flex-basis: 50%; */
    /* flex-basis: 300px; */
    /* flex-basis: 10rem; */
    /* flex-basis: content; */
}

<style>
   .container{
       background-color: powderblue;
       display: flex;
       flex-direction: column;
   }
   .item{
       background-color: tomato;
       color: white;
       border: 1px solid white;
  .item:nth-child(2) {
  	flex-basis: 200px;  
    /* 2번째 child(=item)에 flex-basis 적용 */
   }
</style>
<body>   
   <div class="container">
       <div class="item">1</div>
       <div class="item">2</div>
       <div class="item">3</div>
       <div class="item">4</div>
       <div class="item">5</div>
   </div>
</body>

.item1{
     flex-basis:60%;  
 }
.item2{
	flex-basis:40%; 
 }
 .item3{
    flex-basis:10%; 
 }
 /* item 1,2,3에 각 60%, 40%, 10%의 비율을 적용해 주었기 때문에
    화면이 늘어들던 줄어들던 각 item들의 비율이 유지됨 */

🟣 flex-grow; 속성

특정한 item이 flex-grow를 사용하면 해당 숫자만큼 비례하여 전체 공간을 n등분하여 차지
(기본 grow값은 0)

<style>
   .container{
       background-color: powderblue;
       display: flex;
       flex-flow: row nowrap;
       flex-grow:1;  // 상대값. 절대값(width:30px; height:30px;)보다 우선적용. 
                     // 화면이 늘어나거나 줄어들면 각 item들의 화면을 차지하는 너비의 비율이 1씩 적용
     /* 각 flex(items)들의 비율을 1씩 차지하여 전체 공간을 덮기(전체의 1/n) */
     /* flex-grow:(n); 은 item에 적용하는 속성으로서, item의 너비(화면을 차지하는 상대적 너비)에 적용하지만,
        container에 적용하면 전체 item에 대한 grow비율을 적용해줄 수 있다 */
   }
   .item{
       background-color: tomato;
       color: white;
       border: 1px solid white;
  .item:nth-child(2) {
  	flex-grow:2;  
     /* 각 1/n 씩 차지했지만 2번째 item만 전체의 2의 공간을 차지(우선순위 적용) */
   }
</style>
<body>   
   <div class="container">
       <div class="item">1</div>
       <div class="item">2</div>
       <div class="item">3</div>
       <div class="item">4</div>
       <div class="item">5</div>
   </div>
</body>

   .container{
       background-color: powderblue;
       display: flex;
  	   flex-direction: row;
 	   flex-grow:0;  
           /* flex에 공간을 주지 않는다 */
   }
   .item{
       background-color: tomato;
       color: white;
       border: 1px solid white;
  .item:nth-child(2) {
  	flex-grow:1;  
        /* 다른 item들은 flex-grow가 0인 반면 2번째 item만 공간을 차지하겠다는 명령을 했기 때문에 
     flex-grow가 1이든 2든 3이든 상관없이 남은 공간을 2번째 item이 다 차지하는 것은 같다 */
   }


🟣 flex-shrink; 속성

특정한 item이 "flex-basis:(n)px;" 값을 가지고 있을 경우, flex-shrink를 사용하면 basis값을 (비례하여) 줄이는 효과가 가능하다
(기본 grow값은 0)

  .container{
      background-color: powderblue;
      display: flex;
      flex-flow: row nowrap;
      flex-grow:0;  // 기본값
    }
  .item{
      background-color: tomato;
      color: white;
      border: 1px solid white;
 .item:nth-child(2) {
      flex-basis:500px;
      flex-shrink: 1;  /* 2번째 item이 줄어든다(화면을 줄이면 2번째의 크기가 줄어든다) */
  }

  .container{
      background-color: powderblue;
      display: flex;
      flex-direction: row;
      flex-grow:0;  
    }
  .item{
      background-color: tomato;
      color: white;
      border: 1px solid white;
 .item:nth-child(2) {
      flex-basis:500px;
      flex-shrink: 0;  /* 2번째 item이 줄어들지 않는다(화면을 줄여도 2번째의 크기가 줄어들지 않는다) */
  }

⭕holy Grail Layout
Holy Grail은 성배라는 뜻이며, 이것에 비유해서 아래와 같은 레이아웃을 성배 레이아웃이라고 부른다.

<style>
  .container{              /* 전체 flex 설정 */
     display: flex;
     flex-direction: column;
   }
  header{
     border-bottom: 1px solid grey;
   }
  footer{
     border-top: 1px solid grey;
   }
  .content{    
     display: flex;
   }
  /* Flex 아이템들은 가로 방향으로 배치되고, 자신이 가진 내용물의 width 만큼만 차지.(=inline 요소들 처럼) 
  height는 컨테이너의 높이만큼 늘어난다. */
  .content nav{
     border-right: 1px solid grey;
   }
  .content aside{
     border-left: 1px solid grey; 
   }
  nav, aside{
     flex-basis: 150px;
     flex-shrink: 0;
   }
/* shrink를 0을 주었기 때문에 화면을 줄이면 main의 너비만 줄어들 뿐, nav와 aside는 줄어들지 않는다 */
</style>
<body>
   <div class="container">  /* 전체 flex를 주기 위한 container 생성 */
      <header>
          <h1>KIRIN VELOG</h1>
      </header>
      <section class="content"> /* section 내 nav, main을 담기 위해 class를 주어 핸들링하기 */
          <nav>
               <ul>
                 <li>html</li>
                 <li>css</li>
                 <li>js</li>
               </ul>
          </nav>
          <main>
            제 블로그는 TIL을 정리한 내용입니다.
          </main>
          <aside>
            AD
          </aside>
       </section>
       <footer>
          <a href="https://velog.io/@kirin/Flex">velog 바로가기</a>
       </footer>
    </div>
 </body>
</html>

https://studiomeal.com/archives/197
http://hleecaster.com/css-flexbox-%EC%89%BD%EA%B2%8C-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0/

profile
boma91@gmail.com

0개의 댓글