개요

우리가 보는 웹 사이트들은 대부분 위에서 아래로 구성되어있다. 그리고 이에 맞게 block요소는 화면의 양 끝까지의 너비를 가진다. 따라서 수직 배치는 그렇게 어렵지 않다.
그러나 수평 배치는 조금 얘기가 다르다. 지금은 flex라는 정렬 속성이 생겼기 때문에 쉽게 처리가 가능했지만 예전에는 float와 같은 속성을 이용해서 수평 배치를 해왔었다. 그러나 애초에 float과 같은 속성들은 배치를 위한 속성이 아니였기 때문에 화면 구성을 하는데 어려움이 있었다.

그러다가 flex라는 속성이 등장했고 정렬은 이제 flex로 처리가 가능해졌다. flex자체는 정렬을 위한 것이며 수평 정렬뿐만 아니라 수직 정렬도 가능하다.

flex?

flex는 부모요소인 컨테이너와 아이템으로 구성된다. 간단한 예제를 살펴보자.

<div class="container">
	<div class="item">item 1</div>
	<div class="item">item 2</div>
	<div class="item">item 3</div>
</div>
.container {
  display: flex;
  border: 1px solid;
}
.item {
  border: 1px solid;
  padding : 10px;
}

하위 플렉스 아이템에는 알아보기 쉽게 테두리선과 여백을 주었다.
flex 적용 전 스크린샷 2024-06-29 시간: 16 24 28 flex 적용 후 스크린샷 2024-06-29 시간: 16 24 07

단순히 display: flex 속성을 적용한 것 만으로 위에서 아래로 쌓이던 레이아웃이 왼쪽에서 오른쪽으로 쌓인다.

정렬 축

flex를 잘 사용하기 위해선 flex가 어떤 개념으로 이루어지는지 알아야한다.
flex에는 축의 개념이 있다. 주축과 교차축으로 주축은 main-axis, 교차축은 cross-axis라고 부른다. flex는 주축을 따로 설정할 수 있는데 디폴트로 가로로 설정되어 있으며 주축의 시작 부분을 시작점, 끝 부분을 끝점이라고 부른다.

디폴트가 가로이기 때문에 별도의 설정 없이도 가로 정렬이 된 것을 볼 수 있다. 만약 이 주축을 변경하고싶다면 flex-direction속성을 사용하면 된다.

flex-direction: column;

row는 수평을 의미하고 column은 수직을 의미한다.
기본 속성은 row로 위의 사진을 보면 요소가 왼쪽에서 오른쪽으로 쌓이는 것을 확인할 수 있다.

역방향으로 정렬하는 것도 가능하다.row-reverse, column-reverse속성을 사용하면 된다. 이렇게 하면 1,2,3순서로 작성된 것이 3,2,1의 순서로 배열된다.

레이아웃을 짤 때 중앙정렬을 하는 경우가 가장 많기 때문에 중앙정렬하는 방법을 알아보자.

주축 정렬

justify-content는 주 축의 정렬 방법을 정하는 속성이다.
따라서 수평 중앙에 요소들을 정렬하고싶다면 이렇게 하면 된다.

justify-content: center;

다른 속성 값으로는 위에서 살펴본 시작 점과 끝 점을 사용 할 수 있다. flex-end, flex-start.
그 외에 space-around, space-between이 있다. 그러나 space-around, space-between를 쓰기보다 center와 같이 사용하고 gap속성이나 margin속성에 값을 주어 떨어지게 만들어 사용하는 경우가 더 많다.

아이템 줄바꿈

만약 하나의 플렉스 컨테이너 아래에 여러개의 요소가 있을 때 이들은 하나의 줄로 표현되려고 하기 때문에 아이템의 크기가 변하게된다.

이럴 때 사용할 수 있는 속성은 flex-wrap이다.

기본 속성은 no-wrap으로 아이템들을 여러줄이 아닌 한 줄로 표현하는 값이다.
flex-wrap을 wrap으로 설정하면 자식 아이템이 자신의 크기를 유지하며 컨테이너를 벗어나는 경우 줄바꿈 처리되어 출력된다.

만약 한 줄에서 정해둔 갯수만큼의 요소가 보이기를 원한다면 flex-wrap을 설정하고 컨테이너의 width값과 아이템의 width값을 일치시켜서 딱 들어맞게 할 수 있다. 그냥 wrap을 적용했을 때는 기본적으로 주축의 정렬이 시작접으로 설정되기 때문에 오른쪽에 남는 공간이 생긴다. 그럼 justify-content속성을 center로 하면 중앙 정렬은 되겠지만 한 줄에 하나의 요소만 있는 경우에는 중앙 정렬되어버린다.

왼쪽에서 오른쪽으로 하나씩 추가되는 레이아웃을 생각했다면 부모 요소의 width와 자식 요소의 width값을 계산하여 만약 한 줄에 5개의 요소가 배치되길 원한다면 부모 요소의 width값이 1000px인 경우 자식 요소의 width값을 250px로 맞춰주면 깔끔하게 배치된다.

교차 축 정렬

주축을 살펴봤으니 이제 교차 축 정렬을 살펴보자.

교차축 정렬을 하는 속성은 align-content와 align-items가 있다.

align-content는 아이템이 여러 줄 이상이고 여백이 있을 경우에만 사용할 수 있는 특징이 있다.

기본 값은 stretch로 교차축에 해당하는 값이 auto일 경우 교차 축을 채우기 위해 자동으로 늘어난다.

align-items는 아이템이 한 줄일 경우 사용한다.
기본 값은 stretch로 교차축을 채우기 위해 길이를 최대한 늘리려고한다.

둘의 차이점은 align-content는 여러 줄을 마치 하나의 단위처럼 교차축에 정렬하는 방법이고 align-items는 여러 줄을 각각의 줄처럼 정렬한다.

스크린샷 2024-07-06 시간: 23 09 55 align-content: center를 적용했을 때

스크린샷 2024-07-06 시간: 23 11 15 align-items: center를 적용했을 때

아이템 사이의 간격

gap은 각 아이템 사이의 간격을 주는 속성이다.
예를 들어 display: flex;로 기본 수평 정렬을 했다면 각 요소 사이가 다 붙어있게 될 것이다. 이 때 gap 속성을 사용해서 원하는 만큼 간격을 만들 수 있다.

아이템 순서

order속성은 아이템에 적용하는 속성으로 아이템의 배치를 바꿀 수가 있다. 기본적으로는 부모 태그를 기준으로 가장 첫번째 선언된 태그부터 가장 나중에 선언된 태그순으로 정렬되지만 각각의 아이템의 순서를 바꾸어 출력하고 싶다면 order속성을 사용하면 된다.

order: 1;과 같이 선언하고 음수도 선언이 가능하다.

아이템 비율

flex-grow는 아이템 요소의 너비의 비율을 증가시킬 수 있다. 예를 들어 3개의 아이템이 있고 flex-grow값을 각각 1, 2, 1로 설정한다면 부모요소의 너비를 25%, 50%, 25%씩 차지하게 된다. 주의할 점은 너비가 자동으로 변경될 수 있도록 값이 정해지지 않아야한다는 것이다.

flex-shrink는 flex-grow와는 반대로 아이템의 너비의 비율을 수축시킬 수 있는 속성이다.
그러나 계산하기가 까다로워 자주 사용되지 않는 속성이라고한다.
이 부분은 이해를 못하겠다..

아이템의 기본 너비

flex-basis는 공간 배분 전 기본 너비를 설정한다. 기본 값은 auto로 아이템의 각기 길이 설정으로 너비를 설정한다.

재밌게 flex를 사용해보며 익숙해질 수 있는 사이트가 있다.
플렉스 개구리