CSS flexbox 쉽게 이해하기

CSS를 활용하면 웹 페이지에 HTML 요소들을 요리조리 배치하는 게 가능하다. 물론 CSS 박스모델과 함께 기본적인 display 속성, 그리고 float를 알면 간단한 배치는 어느정도는 가능한데, 여기에 flexbox까지 익히면 요소를 좀 더 자유롭게 배치할 수가 있다. 특히 화면 크기의 변화에 반응하는, 즉 반응형 웹사이트를 만드는 데 유용하다. (물론 정말 전체 페이지 레이아웃을 잘 짜려면 grid까지 알면 좋은데, 그건 복잡하니 나중에 기회가 되면 또 남겨봐야겠다. 이번 포스팅에서는 flexbox만 다룬다.)

display: flex; 또는 display: inline-flex;

일단 모든 요소는 플렉스 컨테이너가 될 수 있다.

div.container {
  display: flex;
}

이렇게 선언하면 flex container 안에 포함된 자식요소들은 모두 flex item이 되고, 부모 컨테이너의 크기와 위치에 따라 자신의 크기와 위치를 변경한다. 이렇게 하면 컨테이너 자체는 block 타입이 유지되어 컨테이너가 화면의 전체 너비를 차지한다.

만약 inline으로 배치하려면 display: inline-flex;를 명시하면 된다. 이러면 컨테이너가 아이템 너비만큼만 차지하게 되고, 화면의 전체 너비가 차기 전까지는 컨테이너가 화면에 나란히 나타난다.

justify-content 속성

일단 부모 컨테이너의 display 속성 값을 flex 또는 inline-flex로 변경하면 모든 하위 요소(flex item)들은 부모 컨테이너의 왼쪽 상단으로 이동한다. (왼쪽 상단이 기본 값이다.)

그래서 만약 flex item들이 정렬되는 옵션을 바꾸고 싶으면 justify-content 속성 값을 조정하면 된다.

.container {
  display: flex;
  justify-content: flex-end;
}

옵션은 총 5개 있다.

  • flex-start — 왼쪽부터 순서대로 배치됨. 아이템 사이 여백 없음.
  • flex-end — 오른쪽에 붙어서 정렬. 아이템 사이 여백 없음.
  • center — 가운데 정렬. 아이템 사이 여백 없음.
  • space-around — 동일한 간격으로 배치. 아이템 사이 여백이 생김.
  • space-between — 동일한 간격으로 배치. 아이템 사이 여백 있으나 첫 번째 요소 앞, 마지막 요소 뒤에는 여백 없음.

그냥 예시로 한 번 보는 게 빠르다.

align-items 속성

이번엔 콘텐츠 높이가 다를 때 세로로 어떻게 정렬할 것인지 정해보자. align-items 속성을 활용한다.

.container {
  align-items: baseline;
}

이것도 옵션이 5개 있다.

  • flex-start — 부모 컨테이너 위쪽 정렬.
  • flex-end — 부모 컨테이너 아래쪽 정렬.
  • center — 부모 컨테이너 가운데 정렬.
  • baseline — 아이템들끼리 아래쪽 정렬. (가장 높은 아이템이 부모 컨테이너 시작점이 됨.)
  • stretch — 부모 컨테이너 꽉 차게 위 아래로 펼쳐서 맞춤 정렬. 이게 기본 값. (만약 요소의 height가 정해져 있다면 펼쳐지지 않으나, min-height 만 지정되어 있거나 height가 따로 명시 안 되어 있다면 펼쳐짐.)

역시나 직접 보는 게 빠르다.

flex-grow, flex-shrink, flex-basis 속성

이제 화면 크기를 늘이거나 줄였을 때 아이템들이 늘어나는 비율을 조절하는 법을 익혀보자. flex-grow, flow-shrink를 사용하면 된다.

값에는 숫자를 넣어서 커지거나 줄어든 화면의 비율을 각 아이템이 얼마나 잡아먹을 것인지 결정하면 된다.

flex-grow는 이런 식으로

.container {
  display: flex;
}

.center {
  width: 100px;
  flex-grow: 2;
}

적용되는 모양새는 이러하다.

이번엔 flex-shrink 적용할 때

.container {
  display: flex;
}

.center {
  width: 100px;
  flex-shrink: 2;
}

나타나는 모습들을 보자.

그리고 이렇게 각 요소(flex item)들이 늘거나 줄어들기 시작하는 기준이 되는 너비를 flex-basis라는 속성을 지정해줄 수 있다.

.container {
  display: flex;
}

.item {
	flex-basis: auto; /* 기본값 */
	/* flex-basis: 0; */
	/* flex-basis: 50%; */
	/* flex-basis: 300px; */
	/* flex-basis: 10rem; */
	/* flex-basis: content; */
}

그리고 flex-grow, flex-shrink, flex-basis 속성들을 한 줄에 단축표기법으로 flex라는 속성 하나에 써줄 수도 있다.

만약 big 클래스는 늘어날 때 2배 더 늘어나고, small 클래스는 줄어들 때 2배로 더 줄어들도록 하려면 이렇게.

.big {
  flex: 2 1 150px;
}

.small {
  flex: 1 2 100px;
}

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, nowrap이 있는데 nowrap이 기본값이다. 그냥 줄어드는 방식. 예시를 보면 바로 이해됨.

align-content 속성

아이템들이 다음 라인으로 배치될 때는 컨테이너 높이가 정해져 있는 경우 세로로 어떻게 정렬할지 align-content 속성으로 결정할 수 있다. (가로로 justify-content 속성을 활용하는 것과 비슷한데 옵션이 stretch로 하나 더 있다. 그리고 이게 기본 값이다.)

이렇게 컨테이너 속성으로 넣어주는 거다.

.container {
  display: flex;
  width: 400px;
  height: 400px;
  flex-wrap: wrap;
  align-content: space-around;
}

.child {
  width: 150px;
  height: 150px;
}

예시를 보자. 각 아이템에 min-height를 적용한 상태.

flex-direction 속성

이건 각 아이템을 축에 따라 어떤 순으로 배치할지 결정하는 방식이다. 사실 별로 쓸 일은 없긴 한데…

컨테이너에다가 flex-direction 속성 값을 4개 옵션으로 줄 수 있다. row(기본값) , row-reverse, column, column-reverse.

예시만 보고 넘어가자.

그리고 이 flex-direction 속성은 flex-wrap과 함께 flex-flow라는 속성에 단축표기법으로도 쓸 수 있다.

아래 두 개는 같은 거다.

.container {
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
}

.container {
  display: flex;
  flex-flow: column wrap;
}

flexbox 속성 중첩해서 사용하기

중첩해서 사용하면 레이아웃 예쁘게 짤 수 있다. 그냥 단순한 예시.

  <div class="main">
    <div class="container">
      <div class="child">
        <h2>Child 1</h2>
      </div>
      <div class="child">
        <h2>Child 2</h2>
      </div>
      <div class="child">
        <h2>Child 3</h2>
      </div>
    </div>
    <div class="container"></div>
  </div>
.main {
  background-color: lightgrey;
  width: 400px;
  height: 400px;
  display: flex;
  align-items: center;
  justify-content: space-around;
}

.container {
  width: 300px;
  height: 300px;
  background-color: dodgerblue;
  border: 1px solid white;
  display: flex;
  flex-direction: column; 
  justify-content: center;
  align-items: center;
}

.child {
  height: 75px;
  width: 75px;
  background-color: whitesmoke;
  border: 1px solid snow;
  display: flex;
  justify-content: center;
  align-items: center;
}

레이아웃 잘 짜는 게 쉬운 일은 아닌 거 같다. 최근에 구글에서 올려준 유튜브 영상이 있는데 보면 많이 도움이 될 듯!

일단 CSS flex 쉽게 알아보기. 끝.

추천 글

댓글 남기기