[CSS] 11. flexbox



11. flexbox

flexbox 개요

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

.container {
    border: 5px solid red;
    // 새로운 방법
    display: flex;

}

.item {
    width: 50px;
    height: 50px;
    border: 3px solid;

    display: inline-block;
    // 인라인이어서 정렬되지 않은 공백이 생긴다.
    // 만약 float 라면
    float: left;
    // 둥둥 뜨기 때문에 자연스럽지가 않다.

}
  • flexable box
  • 수평정렬, 수직정렬하는 새로운 방법
  • 정렬하고 싶은 아이템의 부모 컨테이너에 주는 속성
  • 2차원이 아닌 1차원 배열


용어

  • flex container : 정렬하고 싶은 아이템은 감싼 컨테이너
  • flex item : 정렬하고 싶은 아이템
  • main axis : x축 (주축) - 가로(왼>오)
  • cross axis : y축 (교차축) - 세로(위>아래)


Container - display

.container {
    display: inline flex;
    // 사용 지양
    display: inline-flex;
    // 가운데 - 처리
}
  • block, inline, inline-block : 본인의 앞뒤 요소에 대한 관계
  • 위의 경우가 <display-outside>
  • <display-inside> : flex, grid (내 안쪽에 대한 관계)
  • 완전히 다른 개념이다.


Container - flex-direction

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

.container {
    border: 5px solid red;
    display: flex;
    flex-direction: row-reverse;

}

.item {
    width: 50px;
    height: 50px;
    border: 3px solid;
}
  • Container 에 사용하는 개념
  • 컨테이너 내의 아이템을 배치할 때 사용할 주축 및 방향을 지정하는 것
  • 주축의 위치 (가로, 세로)
  • 주축의 방향 (정방향, 역방향)
  • 총 4가지
  • row : default
  • row-reverse : 오 > 왼
  • column : 세로 + 위 > 아래
  • cloumn-reverse : 세로 + 아래 > 위


Container - flex-wrap, flex-flow (shorthand)

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

.container {
    border: 5px solid red;
    display: flex;
    flex-direction: row-reverse;
    flex-wrap: wrap;
    // item의 width, height가 변하지 않는다.

    // shorthand
    flex-flow: row-reverse wrap

}

.item {
    width: 50px;
    height: 50px;
    border: 3px solid;
}
  • 강제로 한줄에 배치되게 할 것인지, 또는 여러 행에 나눌 것인지
  • 원래는 강제로 한줄에 배치된다 (width 줄어들면서)
  • nowrap : default
  • wrap : 여러 행에 걸쳐 된다 (위 > 아래) (크기 안줄어든다.)
  • wrap-reverse : 여러 행에 걸치며 시작점과 끝점이 바뀐다.
  • flex-flow: flex-direction + flex-flow
  • 공백으로 구분


Item - order

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

.container {
    border: 5px solid red;
    display: flex;
    flex-flow: row-reverse wrap

}

.item {
    width: 50px;
    height: 50px;
    border: 3px solid;
}

.item:nth-child(3) {
    order: -1;
    // 3번이 가장 앞으로 온다.
}

.item:nth-child(4) {
    order: 1;
    // 4가 가장 뒤로 간다.
}
  • flex 내의 아이템의 배치 순서 결정
  • 부모에 flex, grid 되있어야 한다.
  • 0 (default)
  • <integer> : 음수도 사용 가능
  • 오름차순 정렬


Item - flex-grow

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

.container {
    border: 5px solid red;
    display: flex;
    flex-wrap: wrap;

}

.item {
    width: 50px;
    height: 50px;
    border: 3px solid;

    flex-grow : 1;
    // item을 배치하고 남는 공간을 item 갯수만큼 쪼개 각각에 추가
    // 만약 wrap 주고 width를 증가시킨다면?
    // 위 3 아래 2개일때
    // 3개 2개 width 값 다르게 해서 각각의 줄 꽉 채워진다.
}

.item:nth-child(2) {
    flex-grow: 2;
    // 남은 공간을 3으로 쪼개서 2를 가져간다.
}

.item:nth-child(3) {
    flex-grow: 1;
    // 남은 공간을 3으로 쪼개서 1을 가져간다.
}

  • 본인이 차지할 수 있는 공간보다 작거나 크게 변경할 수 있는 것
  • 주어진 공간보다 item의 요소가 작을 때
  • 0 (default)
  • <number>: 음수 금지
  • float 가능
  • 남는 공간을 쪼개서 각각의 Item에 할당


Item - flex-shrink

<div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
</div>

.container {
    border: 5px solid red;
    display: flex;
    flex-wrap: wrap;

}

.item {
    width: 50px;
    height: 50px;
    border: 3px solid;
}

.item:nth-child(1) {
    flex-shrink: 0;
    // 컨테이너의 width 줄어도 1번은 안줄어든다
    // 나머지가 더 많이 줄어든다
}

.item:nth-child(3) {
    flex-grow: 2;
    // 3번이 줄어드는 속도가 다른 것 보다 훨씬 빠르다.
    // 줄어든 영역을 나눠가졌는데 3번이 3개중 2개 가져간 것
}

  • flex-grow와 유사하지만 정 반대
  • 주어진 공간보다 item의 요소가 클 때
  • 1 (default)
  • 이미 기본값으로 1을 갖고 있기 때문에 width 줄어들 때 다같이 줄어들었던 것
  • 소수점 가능
  • grow와 default 값 다른 것 잊지말기

Item - flex-basis

<div class="container">
    <div class="item">플렉스</div>
    <div class="item">1</div>
    <div class="item">1</div>
</div>

.container {
    border: 5px solid red;
    display: flex;

}

.item {
    height: 50px;
    border: 3px solid;
    // width 지정 안하면?
    // 컨텐츠 크기만큼 크기가 설정된다.
    // 1 > 2 === 3
    flex-grow: 1;
    // 컨텐츠 영역을 제외하고 나눠갖는다
    // 1 > 2 === 3
    flex-basis: 100px;
    // 컨텐츠 영역으로 갖던게 사라지고 모두 같아진다.
    flex-basis: 0;
    // 초기 컨텐츠 영역을 0으로 갖게 되므로 나머진 3영역을 똑같이 주는 것

}

.item:nth-child(1) {
    flex-grow: 5;
}

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

.item:nth-child(3) {
    flex-grow: 3;
}

// 컨텐츠 박스 기준으로 width 값이 5:1:3

  • 플렉스 아이템의 초기 크기를 지정한다.
  • grow, shrink 되지 않았을 때의 원래 width 값
  • <width>, <percentage>


Item - flex (shorthand)

<div class="container">
    <div class="item">플렉스</div>
    <div class="item">1</div>
    <div class="item">1</div>
</div>

.container {
    border: 5px solid red;
    display: flex;

}

.item {
    height: 50px;
    border: 3px solid;
    flex: 1; // flex-grow
    flex: 1 50px; // flex-grow flex-basis 
    // 무조건 첫번째 값은 grow 하기
    flex: 1 5 // grow shrink
    flex: 1 5 50px // grow shrink basis

}

  • flex-grow + flex-shrink + flex-basis
  • 모두 optional
  • 기존 shorthand는 작성하지 않으면 initial 값이 되었지만
  • flex-basis: auto 가 아닌 0이 된다.
  • auto는 컨텐츠 크기에 따라 각각의 크기가 다르고 0은 동일하기 때문에 0이 더 좋다.
  • 값이 한 개일 때, 면 flex-grow
  • or 면 flex-basis
  • initial === flex: 0 1 auto
  • auto === flex: 1 1 auto
  • none === flex: 0 0 auto


Container - justify-content

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

.container {
    border: 5px solid red;
    display: flex;
    justify-content: flex-start;
    // 주축이 시작되는 위치부터 정렬하겠다. 1 2 3 4 5 - - -
    justify-content: flex-end;
    // 주축이 끝나는 위치부터 정렬하겠다. - - - 1 2 3 4 5
    justify-content: center;
    // 주축을 기준으로 가운데 정렬 - - 1 2 3 4 5 - -
    justify-content: space-between;
    // 시작과 끝은 공간 없이, 가운데들은 여백 똑같이 분배 1  2  3  4  5 
    justify-content: space-around;
    // 각각의 item의 양옆으로 여백 간격을 똑같이 분배 *1**2**3**4**5*

    flex-direction: row-reverse
    justify-content: flex-start;
    // 주축이 시작되는 위치부터 정렬하겠다.  - - - 5 4 3 2 1
    justify-content: flex-end;
    // 주축이 끝나는 위치부터 정렬하겠다. 5 4 3 2 1 - - -
}

.item {
    width: 50px;
    height: 50px;
    border: 3px solid;
}

  • main 축에 관한 이야기
  • 주축을 기준으로 item 정렬을 어떻게 할 것인가.
  • container 에 주는 속성


Container - align-itmes

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

.container {
    border: 5px solid red;
    display: flex;
    justify-content: space-between;
    align-items: stretch; // (default) 위에서 끝까지 
    align-items: flex-start; // 교차축의 시작부분
    align-items: flex-end; // 교차축의 끝부분
    align-items: center; // 교차축의 가운데
}

.item {
    width: 50px;
    height: 50px;
    border: 3px solid;
}

  • cross 축에 관한 이야기
  • 전체 컨테이너 입장해서 item row를 어느 높이에 지정할지
  • 덩어리 한 줄을 어느 height에 위치 시키냐
  • 기준이 교차축의 방향
  • content-wrap === nowrap 으로 한 줄일 때 사용


Container - align-content

<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 class="item">6</div>
    <div class="item">7</div>
</div>

.container {
    width: 400px;
    border: 5px solid red;
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap
    align-content: space-around; // justify-content처럼 사용할 수 있다.
}

.item {
    width: 50px;
    height: 50px;
    border: 3px solid;
}

  • content-wrap === wrap 으로 여러 줄 일때
  • 여러 줄에 관한 이야기
  • 여러 줄 뭉텅이간의 정렬


Item - align-self

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

.container {
    width: 400px;
    border: 5px solid red;
    display: flex;
    flex-wrap: wrap
    // 1 2
    // 3 4
    // 5
    // 컨테이너가 3개의 영역으로 나눠진다.
    align-items: center;
    // 3개로 나눠진 본인의 컨테이너 기존 height의 center
}

.item {
    width: 150px;
    height: 50px;
    border: 3px solid;
}

.item:nth-child(4) {
    align-self: flex-start;
    // 한 요소의 align-item 만 변경하고 싶을 때
    // align-item 과 사용하는 값 똑같다.
    // stretch 로 사용하고 싶으면 height: auto + align-item: stretch
}

  • item에 사용할 수 있는 property


나의 회고 🤫

flex 사용이 대중화되면서 나도 table 대신 flex를 자주 썼었는데,
항상 간단하게 사용했어서 이렇게 많은 속성이 있다는 것을 처음 알았다.
덕분에 뭅스터 배너를 어떻게 변경하면 좋을지 구상이 잡혔다!
css 에 대해 배울 수록 그동안 내 코드의 레거시가 떠오른다…..
기대되면서도 언제 다 수정하지 싶은….ㅎㅎ