Flexbox Layout

divedeepp·2022년 2월 22일
0

CSS3

목록 보기
20/21

Flexbox?

Flexbox는 모던 웹을 위하여 제안된, 기존 레이아웃보다 더 세련된 방식의 CSS3의 새로운 레이아웃 방식이다.

element의 사이즈가 불명확하거나 동적으로 변화할 때에도 유연한 레이아웃을 실현할 수 있다. 또, 복잡한 레이아웃이라도 적은 코드로 보다 간단하게 표현할 수 있다.

이해를 돕기 위해 간단한 flexbox 레이아웃을 만들어 보자.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Flexbox Layout Example</title>
  <style>
    .flex-container {
      margin: 10px;
      padding: 15px;
      border-radius: 5px;
      background: #60B99A;
    }

    .flex-item {
      margin: 10px;
      padding: 20px;
      color: #fff;
      text-align: center;
      border-radius: 5px;
      background: #4584b1;
    }
  </style>
</head>
<body>
  <div class="flex-container">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
  </div>
</body>
</html>

<div> element는 block level element이므로 수직 정렬된다. 이를 수평 정렬하려면 자식 element를 inline-block으로 지정하거나 float property를 지정한다.

.flex-item {
  display: inline-block;
  /* or */
  float: left;
}

이 때 각 자식 element를 부모 element 내에서 균일하게 정렬하기 위해서는 각 자식 element의 너비를 %로 지정하는 등 번거로운 처리가 필요하다. 자식 element의 사이즈가 불명확하거나 동적으로 변화할 때에는 더욱 처리가 복잡해진다. grid 시스템을 사용할 수도 있으나 라이브러리를 로드해야하는 등의 번거로움이 존재한다.

Flexbox를 사용하여 위 예제를 부모 element 내에서 균등하게 수평 정렬해보자. 부모 element에 아래와 같이 코드 두 줄을 추가하면 된다.

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

이처럼 Flexbox를 사용하면 기존 방식에 비해 매우 간단히 레이아웃을 처리할 수 있다.

Flexbox의 장점을 정리해보면 아래와 같다.

  • element의 상하좌우 및 수평 정렬, 순서 변경이 간단하다.
  • element의 간격 조절이 간단하다.

비교적 최신 브라우저가 아니면 vendor prefix를 사용해야한다.


Flexbox 사용법

Flexbox 레이아웃은 flex item이라 불리는 다수의 자식 element와 이들을 포함하는 flex-container라 불리는 부모 element로 구성된다.

flexbox를 사용하기 위해서 부모 element의 display property에 flex를 지정한다. 만약, 부모 element가 inline element인 경우 inline-flex를 지정한다.

.flex-container {
  display: flex;
}

/* if element is inline */
.flex-container {
  display: inline-flex
}

flex 또는 inline-flex는 부모 element에 반드시 지정해야하는 유일한 속성이며, 자식 element는 자동적으로 flex item이 된다.


Flexbox Container에 관련된 property들

flex-direction property

flex container의 주축(main axis) 방향을 설정한다.

property value에 따라 다음과 같다.

  • row : 좌에서 우로 수평 배치된다. 기본값
.flex-container {
  flex-direction: row;
}

  • row-reverse : 우에서 좌로 수평 배치된다.
.flex-container {
  flex-direction: row-reverse;
}

  • column : 위에서 아래로 수직 배치된다.
.flex-container {
  flex-direction: column;
}

  • column-reverse : 아래에서 위로 수직 배치된다.
.flex-container {
  flex-direction: column-reverse;
}

flex-wrap property

flex container의 여러 개의 flex item을 1행 또는 복수행으로 배치한다.

property value에 따라 다음과 같다.

  • nowrap : flex item을 개행하지 않고, 1행에 배치한다. 각 flex item의 너비는 flex container에 들어갈 수 있는 크기로 축소된다. 기본값.
.flex-container {
  flex-wrap: nowrap;
}

<!DOCTYPE html>
<html>
<head>
  <title>Flexbox</title>
  <meta charset="UTF-8">
  <style>
  .flex-container {
    width: 500px;
    margin: 10px;
    padding: 15px;
    border-radius: 5px;
    background: #60B99A;

    display: flex;
    flex-wrap: nowrap;
  }

  .flex-item {
    margin: 10px;
    padding: 20px;
    color: #fff;
    text-align: center;
    border-radius: 5px;
    background: #4584b1;
  }
  </style>
</head>
<body>
  <div class="flex-container">
    <div class="flex-item">11111</div>
    <div class="flex-item">22222</div>
    <div class="flex-item">33333</div>
    <div class="flex-item">44444</div>
    <div class="flex-item">55555</div>
  </div>
</body>
</html>

하지만 flex item들의 width의 합계가 flex container의 width보다 큰 경우에 flex container를 넘치게 된다. 이 때 overflow: auto; 를 지정하면 가로 스크롤이 생기며 container를 넘치지 않는다.

<!DOCTYPE html>
<html>
<head>
  <title>Flexbox</title>
  <meta charset="UTF-8">
  <style>
  .flex-container {
    width: 500px;
    margin: 10px;
    padding: 15px;
    border-radius: 5px;
    background: #60B99A;

    display: flex;
    flex-wrap: nowrap;
    overflow: auto;
  }

  .flex-item {
    margin: 10px;
    padding: 20px;
    color: #fff;
    text-align: center;
    border-radius: 5px;
    background: #4584b1;
  }
  </style>
</head>
<body>
  <div class="flex-container">
    <div class="flex-item">11111111</div>
    <div class="flex-item">22222222</div>
    <div class="flex-item">33333333</div>
    <div class="flex-item">44444444</div>
    <div class="flex-item">55555555</div>
  </div>
</body>
</html>

  • wrap : flex item들의 width 합계가 flex container의 width보다 큰 경우, flex item들을 여러 행에 배치한다. 기본적으로 좌에서 우로, 위에서 아래로 배치된다.
.flex-container {
  flex-wrap: wrap;
}

  • wrap-reverse; : wrap과 동일하나, 아래에서 위로 배치된다.
.flex-container {
  flex-wrap: wrap-reverse;
}

flex-flow property

flex-directionflex-wrap 을 한 번에 설정할 수 있다. 기본값은 row nowrap이다.

.flex-container {
  flex-flow: <flex-direction> <flex-wrap>;
}

justify-content property

flex container의 main axis를 기준으로 flex item을 수평 정렬한다.

property value에 따라 다음과 같다.

  • flex-start : main start(좌측)을 기준으로 정렬한다. 기본값.
.flex-container {
  justify-content: flex-start;
}

  • flex-end : main end(우측)을 기준으로 정렬한다.
.flex-container {
  justify-content: flex-end;
}

  • center : flex container의 중앙에 정렬한다.
.flex-container {
  justify-content: center;
}

  • space-between : 첫 번째와 마지막 flex item은 좌우 측면에 정렬되고, 나머지는 균등한 간격으로 정렬된다.
.flex-container {
  justify-content: space-between;
}

  • space-around : 모든 flex item은 균등한 간격으로 정렬된다.
.flex-container {
  justify-content: space-around;
}

align-items property

flex item을 flex container의 수직 방향(cross axis)으로 정렬한다.

property value에 따라 다음과 같다.

  • stretch : 모든 flex item은 flex container의 높이(cross start에서 cross end까지의 높아)에 꽉 찬 높이를 갖는다. 기본값
.flex-container {
  align-items: stretch;
}

  • flex-start : 모든 flex item은 flex container의 cross start 기준으로 정렬된다.
.flex-container {
  align-items: flex-start;
}

  • flex-end : 모든 flex item은 flex container의 cross end 기준으로 정렬된다.
.flex-container {
  align-items: flex-end;
}

  • center : 모든 flex item은 flex container의 cross axis의 중앙에 정렬된다.
.flex-container {
  align-items: center;
}

  • baseline : 모든 flex item은 flex container의 baseline을 기준으로 정렬된다.
.flex-container {
  align-items: baseline;
}

align-content property

flex container의 cross axis를 기준으로 flex item을 수직 정렬한다.

property value에 따라 다음과 같다.

  • stretch : 모든 flex item은 균등하게 분배된 공간에 정렬되어 배치된다. 기본값.
.flex-container {
  align-content: stretch;
}

  • flex-start : 모든 flex item은 flex container의 cross start 기준으로 stack 정렬된다.
.flex-container {
  align-content: flex-start;
}

  • flex-end : 모든 flex item은 flex container의 cross end 기준으로 stack 정렬된다.
.flex-container {
  align-content: flex-end;
}

  • center : 모든 flex item은 flex container의 cross axis의 중앙에 stack 정렬된다.
.flex-container {
  align-content: center;
}

  • space-between : 첫 번째 flex item 행은 flex container의 상단에 마지막 flex item의 행은 flex container의 하단에 배치되며 나머지 행은 균등하게 분할된 공간에 정렬 배치된다.
.flex-container {
  align-content: space-between;
}

  • space-around : 모든 flex item은 균등하게 분할된 공간 내에 배치 정렬된다.
.flex-container {
  align-content: space-around;
}


Flexbox Item에 관련된 Property

float, clear, vertical-align property는 flex item에 영향을 주지 않는다.

order property

flex item의 배치 순서를 지정한다. HTML 코드를 변경하지 않고, order property에 값을 지정하는 것으로 간단히 재배치할 수 있다.

기본 배치 순서는 flex container에 추가된 순서이고, 값이 클 수록 뒤에 배치된다. 기본값은 0이다.

.flex-item {
  order: 정수값;
}

flex-grow

flex item의 너비에 대한 확대 인자를 지정한다.

기본값은 0이고, 음수값은 무효하다.

.flex-item {
  flex-grow: 양의 정수값;
}

모든 flex item이 동일한 값을 가지면 모든 flex item은 동일한 너비를 갖는다.

값이 클 수록 다른 flex item보다 더 넓은 너비를 갖는다.

flex-shrink

flex item의 너비에 대한 축소 인자를 지정한다.

기본값은 1로 모든 flex item이 축소된 상태로 지정되고, 음수값은 무효하다.

.flex-item {
  flex-shrink: 양의 정수값;
}

0을 지정하면 축소가 해제되어 원래의 너비를 유지한다.

flex-basis

flex item의 너비 기본값을 px, %, 등의 단위로 지정한다.

기본값은 auto이다.

.flex-item {
  flex-basis: auto;
}

flex

flex-grow, flex-shrink, flex-basis property들을 한 번에 지정할 수 있다.

기본값은 0 1 auto이다.

W3C에서는 이 property보다는 개별적으로 기술하는 것을 추천한다.

.flex-item {
  flex: none | auto | [ <flex-grow> <flex-shrink>? || <flex-basis> ];
}

align-self

align-items property보다 우선하여 개별 flex item을 정렬한다.

기본값은 auto이다.

.flex-item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}


참고문헌

https://poiemaweb.com/css3-flexbox

profile
더깊이

0개의 댓글