[CSS] Flexbox

DONGHO JANG·2022년 2월 23일
0

CSS-Study

목록 보기
3/4
post-thumbnail

이번 글에서는 flexbox를 다뤄보겠다.
flexbox는 행과 열 형태로 항목을 배치하는 일차원 레이아웃 메서드이다.

왜 flexbox를 써야해?

flexbox가 없던 시절에 우리는 floats와 position을 가지고 CSS 레이아웃을 대부분 작성했다. 이 둘은 잘 작동했지만, 어떤 면에서는 너무 불편했다. 그래서 등장한 것이 바로 flexbox! flexbox는 많은 레이아웃 작업을 훠어얼씬 더 쉽게 만들어준다.

간단한 예제

아래 예제를 살펴보자. <header> 요소와 세 개의 <article>를 포함한 <section> 요소가 있다.

flexbox 지정하기

먼저 어떤 요소들을 flexbox로 레이아웃 할지 생각해봐야 한다. 그리고 영향을 주고 싶은 요소의 부모 요소display: flex; 값을 준다. 여기서 주의할 점은 반드시 내가 flexbox를 만들고 싶은 요소의 부모 요소에 flex를 주어야 한다. 예제의 경우 우리는 <article> 요소를 레이아웃하길 원하므로 그의 부모 요소인 <section>에 flex 속성값을 지정해야 한다.

section {
  display: flex;
}

놀랍지않나? 딱 한 줄의 코드만으로 단의 크기가 동일한 다단 레이아웃을 갖게 되었고, 단의 높이도 다 같아졌다!

꼭 알아야 할 용어들

요소들이 flexbox로 레이아웃될 때 그 상자들은 두 개의 축을 따라 배치된다.

아래의 용어들은 flexbox를 이해하기 위해서 반드시 알아두어야 할 용어들이다.

  • 주축(main axis)은 flex item이 배치되고 있는 방향으로 진행하는 축이다.
    • 주축의 시작과 끝을 일컬어 main startmain end라고 한다.
  • 교차축(cross axis)은 배치되고 있는 방향에 직각을 이루는 축이다.
    • 교차축의 시작과 끝을 일컬어 cross startcross end라고 한다.

배치되고 있는 방향이 뭐시여?

flexbox는 주축이 진행되는 방향이 있다. 기본값은 row로 설정되어 행 레이아웃(좌측에서 우측)으로 배치된다.

또한 이것의 방향을 바꿀 수도 있는데, flex-direction 속성을 이용하면 된다. 다음 선언문을 <section>에 추가해보자.

flex-direction: column;

이로써 항목들을 열 레이아웃(위에서 아래)으로 설정했다. 마치 flexbox 레이아웃을 사용하기 전으로 되돌아간 것 같은 느낌이 든다.

참고로, row-reversecolumn-reverse 속성값을 사용하면 역방향으로 배치할 수도 있다!

  • display: flex가 설정된 부모 요소를 일컬어 flex container라고 한다.
  • flex container 내부에 flexbox로 레이아웃 되는 항목을 일컬어 flex item이라고 한다.

flex item이 너무 많아졌어!

flex item이 적을 때는 상관없지만 요소가 많아지기 시작하면 레이아웃 너비 또는 높이가 고정 크기를 갖고 있어 결국 요소가 컨테이너에서 이탈하면서 레이아웃이 깨지게 된다.

그것을 해결해줄 만한 속성들이 있다.

flex: 200px;
flex-wrap: wrap;

flex: 200px 의 의미는 각 요소에 적어도 200px 너비가 지정되었다는 의미이다. 만약 최소 너비로 행을 채우는데 대형이탈된 요소가 생겼다면 그 요소는 flex-wrap: wrap 에 의해 다음 행으로 넘어간다. 그리고 모든 요소들은 다시 알맞게 크기가 조정되어 분배가 된다. 얼마나 좋은가?

flex-flow

flex-direction: row;
flex-wrap: wrap;

꿀팁! 위 두 줄의 코드를 하나로 합칠 수 있다.

flex-flow: row wrap;

flex item의 비율 조절

article {
	flex: 1;
}

위 코드는 각 flex item이 기본 축을 따라 남은 공간을 어느 정도나 점유할지를 결정하는 단위가 없는 비율 값이다. 그 말은 즉슨 패당과 여백이 지정된 이후 남은 여분의 공간을 모두 동등한 크기로 점유하게 된다는 의미이다.

아래의 예제에서는 3개의 flex item들이 1:1:1 비율로 배분되었다.

만약 세 번째 요소에 flex: 2 를 넣으면 어떻게 될까? 그럼 flex item들은 1:1:2 비율로 배분될 것이다.

또한 flex 값 내에서 최소 크기 값을 지정할 수 있다.

article {
  flex: 1 200px;
}

article:nth-of-type(3) {
  flex: 2 200px;
}

이것은 기본적으로 아래의 순서대로 공간이 배분된다.

  1. 각 flex item은 먼저 사용 가능한 공간에서 최소 공간인 200px를 부여 받는다.
  2. 나머지 사용 가능한 공간은 비례 단위에 따라 분배된다.

flexbox의 꽃, 수평 및 수직 정렬

위의 예제는 일반적인 flex 레이아웃을 취하고 있다. 이제 새로운 속성을 통해서 버튼들의 위치를 수평 및 수직으로 정렬해보겠다.

div {
  display: flex;
  align-items: center;
  justify-content: space-around;
}

와우! 버튼들의 위치를 보니 마음이 편안해진다. 새로운 두 가지 속성에 대해서 자세히 알아보자.

  1. justify-content 는 flex item이 주축 상 어디에 놓이는지를 결정한다.

  2. align-items 는 flex item이 교차축 상 어디에 놓일 지를 제어한다.

만약 flex item이 배치되고 있는 방향이 row 이고, justify-contentcenter 라면 주축(좌측에서 우측)에서 중앙에 배치될 것이다.

만약 flex item이 배치되고 있는 방향이 column 이고, justify-contentcenter 라면 주축(윗쪽에서 아랫쪽)에서 중앙에 배치될 것이다.

이 두 가지의 차이를 잘 이해해야 한다.

이제 조금 더 깊게 들어가보자.

justify-content (주축)

  • flex-start : 기본값이며, 모든 항목이 주축의 시작 부분에 놓인다.
  • flex-end : 모든 항목이 주축의 끝 부분에 놓인다.
  • center : 항목들이 주축의 중심에 놓인다.
  • space-around : 모든 항목을 주축을 따라 고르게 분배하고 양쪽 끝에 약간의 공간도 남겨둔다.
  • space-between : space-aroumd 와 유사하나, 양쪽 끝에 공간은 남기지 않는다.

align-items (교차축)

  • stretch : 기본값이며, 교차축 방향으로 부모 요소를 채우기 위해 모든 flex item을 연장한다. (이 방식 때문에 모든 항목이 같은 높이를 가지게 되는 것이다.)
  • center : 모든 항목이 자기들 고유의 면적을 유지하는 동시에 교차축의 중심에 놓인다.
  • flex-start : 교차축의 시작 부분에 놓인다.
  • flex-end : 교차축의 끝 부분에 놓인다.

align-self 속성을 이용하면 flex item 개별 항목을 배치할 수 있다!

flex item 순서 정하기

flexbox에는 소스 순서에 영향을 미치지 않고 flex item의 레이아웃 순서를 변경하는 기능도 있다.

button:first-child {
  order: 1;
}

본래 첫번째에 자리 잡고있던 'Smile' 단추가 주축의 끝으로 이동했다. 왜 이렇게 됐는지 살펴보자.

  • 기본값으로 모든 flex item들은 order 값이 0이다.
  • 순위값이 높은 flex item들은 순위값이 낮은 항목들보다 나중에 나타난다.
  • 'Smile' 버튼이 order 값이 가장 높기 때문에 제일 뒤로 이동했다.

그렇다면 'Smile' 버튼을 맨 앞으로 보내려면 어떻게 해야할까? 'Smile' 버튼의 order 값을 0보다 작게 해주면 된다.

최종 복습

위의 예제를 하나하나 뜯어보면서 복습해보자. 예제의 HTML의 구조는 다음과 같다. 세 개의 <article> 를 포함하는 <section> 요소가 있다. 세 번째 <article> 은 세 개의 <div> 를 포함하고 있다.

먼저 <section> 의 자식들을 flexbox로 취급해 배치하였다.

section {
  display: flex;
}

다음으로 <article> 들에게 각각 200px를 부여하고 남은 빈 공간은 1:1:3만큼 채워넣는다. 그리고 세 번째 <article> 요소의 자식들을 flexbox로 배치하는데 열 방향으로 배치한다.

article {
  flex: 1 200px;
}

article:nth-of-type(3) {
  flex: 3 200px;
  display: flex;
  flex-flow: column;
}

다음으로 세 번째 <article> 요소의 첫 번째 <div> 를 선택해서 100px의 최소 높이를 주기 위해 flex:1 100px; 을 사용한다. 그리고 그것의 자식들을(<button> 요소들) flexbox로 배치했다. 이 요소들은 행 방향으로 배치되며, 줄 바꿈을 하고 중심에 정렬한다.

article:nth-of-type(3) div:first-child {
  flex:1 100px;
  display: flex;
  flex-flow: row wrap;
  align-items: center;
  justify-content: space-around;
}

마지막으로, 우리는 버튼에 1 auto라는 flex 값을 부여한다. 조금 익숙치 않을텐데, 브라우저 창의 폭을 한번 조정해 보면 이해가 된다. 버튼은 최대한의 공간을 차지하려 하고 동일 선상에 가능한 많은 요소를 놓으려고 한다. 그러나 해당 요소들이 더 이상 동일 선상에 안착할 수 없을 경우 새로운 줄로 밀려난다.

button {
  flex: 1 auto;
  margin: 5px;
  font-size: 18px;
  line-height: 1.5;
}
profile
'Slow Steady'를 지향하는 대학생 개발자입니다.

0개의 댓글