flex를 배우자

8296 단어 CSSCSS

저번주에는 float와 클리어링 BFC 등에 대한 글을 작성했는데 고려해야 할 것이 많아서 레이아웃을 작성하기 어려웠다. 그래서 이번에는 float 이후에 개발된 flexbox에 대해 알아보려고 한다. 당연히 float 이후에 생겨난 레이아웃 메소드이기 때문에 float보다 사용하기에 유용한 점이 있다. 그렇다면 float는 이제 쓸모가 없을까?

크로스 브라우징이 중요한 웹에서는 float가 아직 사용되어야 하는 경우가 있다. Can I use에서 확인해본 결과 float는 대부분의 브라우저에서 지원하는 반면 flex는 IE에서 제한적으로 지원하고 있다. 심지어 다음 시간에 배울 grid는 flex보다도 더 제한적이었다. 따라서 구형 브라우저를 지원해야 한다면 float를 사용하고, 그럴 필요가 없다면 더 편한 flex나 grid를 사용해도 될 것 같다.


Flexbox

float는 다음과 같은 requirements에 효과적인 방법이 되지 못한다. 그러나 flexbox를 사용하면 더 쉽고 유연하게 레이아웃을 만들 수 있다.

  • 부모 요소 내부에 포함된 블록 콘텐츠를 세로로 중심부에 맞추기.
  • 사용 가능한 너비와 높이에 관계없이 하나의 컨테이너에 포함된 모든 자녀 요소가 주어진 너비와 높이를 똑같은 크기로 점유하기.
  • 다단 레이아웃에 포함된 모든 단이 서로 다른 크기의 콘텐츠를 포함하고 있더라도 동일한 높이로 채택하기.

즉, flexbox는 우리들이 원하는 레이아웃을 쉽게 만들수 있게 도와주는 도구이다.


main-axis & cross-axis

먼저 flexbox를 사용하기 위해서는 어떤 요소에 display: flex로 설정해야 한다. 이때 display:flex 설정해주는 요소는 정렬되어야 할 아이템들이 담겨있는 컨테이너이다. 이렇게 flex로 설정하고 나면 기본 축 (main-axis)과 교차 축(cross-axis)이라는 것이 생긴다. 기본 축는 가로 방향으로 웹 페이지를 가로지르는 축이다. 그리고 교차 축는 기본 축에 수직이 되는 방향의 축이다.

위는 flex-directionrow일 때 적용되는 방향이다. 기본적으로 flex-directionrow로 설정되어 있기 때문에 아무것도 건드리지 않는다면 기본 축은 수평이고 교차 축은 수직이다. 만약 flex-direction:column으로 하면 기본 축이 수직이 되고, 교차 축이 수평이 된다.


justify-content

justify-content는 기본 축에서 flex item들을 어떻게 배치할 지를 정한다. justify-content에는 다음과 같은 값을 가질 수 있다. 만약 flex-direction이 변경되면 아래의 속성 값들도 축에 따라 다르게 나타난다.

  1. flex-start : 기본 설정으로, 플렉스 요소는 플렉스 컨테이너의 앞쪽에서부터 배치됩니다.
  2. flex-end : 플렉스 요소는 플렉스 컨테이너의 뒤쪽에서부터 배치됩니다.
  3. center : 플렉스 요소는 플렉스 컨테이너의 가운데에서부터 배치됩니다.
  4. space-between : 플렉스 요소는 요소들 사이에만 여유 공간을 두고 배치됩니다.
  5. space-around : 플렉스 요소는 앞, 뒤, 그리고 요소들 사이에도 모두 여유 공간을 두고 배치됩니다.
  6. space-evenly: 플렉스 요소 앞, 뒤, 그리고 요소들 사이에서 모두 여유 공간을 두고 배치되지만 모두 같은 간격을 가집니다.

align-items

align-items는 교차 축에서 flex item들을 어떻게 배치할 지를 정한다. 만약 flex-direction이 변경되면 당연히 메인 축과 교차 축도 다르기 때문에 아래의 속성 값들도 축에 따라 다르게 나타난다.

  1. stretch: 아이템들이 수직축 방향으로 끝까지 쭈욱 늘어납니다.
  2. flex-start: 아이템들을 시작점으로 정렬합니다.
  3. flex-end: 아이템들을 끝으로 정렬합니다. flex-direction이 row(가로 배치)일 때는 아래, column(세로 배치)일 때는 오른쪽이에요.
  4. center: 아이템들을 가운데로 정렬합니다.
  5. baseline: 아이템들을 텍스트 베이스라인 기준으로 정렬합니다.

flex-wrap

flex 요소를 담고 있는 컨테이너의 크기가 변경될 때 그 안의 flex요소들을 어떻게 배치할 지에 대한 것으로 반응형 웹페이지를 만들 때 중요한 역할을 한다.

속성 값으로는 no-wrap, wrap, wrap-reverse가 있다. no-wrap은 컨테이너의 크기가 줄어들어도 flex요소의 줄바꿈이 일어나지 않고 컨테이너의 넓이를 넘어서서 배치된다. wrap은 만약 flex요소가 배치될 공간이 없으면 다음 줄에 배치된다. wrap-reverse는 flex요소가 배치될 공간이 없을 시 아래줄에 배치되는 것이 아니라 위에 배치된다.


flex-flow

flex-directionflex-wrap을 한꺼번에 지정할 수 있는 단축 속성이다. 반응형으로 웹페이지를 제작할 일이 많을 터이니 다음과 같이 사용하도록 하자.

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

이는 아래처럼 간략하게 표현할 수 있다.

flex-flow: row wrap;

align-content

flex-wrap:wrap으로 설정해서 flex요소들이 두줄에 걸쳐 나올 때 사용하면 좋을 속성이다. justify-content에서 space-between, space-around, space-evenly 등의 값이 메인 축에 있는 flex요소들의 간격들을 조정해주는 것이었다면 align-content는 두줄 이상으로 flex 요소가 되었을 때 그 줄 들의 간격을 조정하는 것이다. 다음과 같은 속성값들을 가질 수 있다.

  1. stretch : 기본 설정으로, 플렉스 라인의 높이가 남는 공간을 전부 차지하게 됩니다.
  2. flex-start : 플렉스 라인은 플렉스 컨테이너의 앞쪽에 뭉치게 됩니다.
  3. flex-end: 플렉스 라인은 플렉스 컨테이너의 뒤쪽에 뭉치게 됩니다.
  4. center : 플렉스 라인은 플렉스 컨테이너의 가운데에 뭉치게 됩니다.
  5. space-between : 플렉스 라인은 플렉스 컨테이너에 고르게 분포됩니다.
  6. space-around : 플렉스 라인은 플렉스 컨테이너에 고르게 분포됩니다. 단, 양쪽 끝에 약간의 공간을 남겨둡니다.
  7. space-evenly: 플렉스 요소 앞, 뒤, 그리고 요소들 사이에서 모두 여유 공간을 두고 배치되지만 모두 같은 간격을 가집니다.

gap

세부적인 레이아웃을 잡기 위해서 간격을 지정할 수 있어야 한다.

1) 컨테이너와 컨텐츠의 간격

2) 컨텐츠 간의 간격

그러나 margin을 이용해서 요소들간의 간격을 지정하면 컴포넌트 간의 배치하고 컨트롤하는데 문제가 생길 수 있다. gap은 엘리먼트 요소들 사이에만 공간을 만들기 때문에 gap을 사용하면 좋다. margin의 경우 주변에 요소가 있던지 말던지 그냥 지정한 값을 가지는데 gap의 경우에는 인접한 요소가 없다면 공간을 만들지 않는다.

gap: 10px 5px;

부모 요소에 다음 처럼 설정하면 상하 10px 좌우 5px gap이 생성된다.


order

생성된 flexbox레이아웃에 각 요소들의 순서를 정할 수 있는 속성이다. 각 요소에 order를 준 경우 order로 설정한 값이 더 작을 수록 앞부분에 위치한다. 음수로 값을 설정할 수도 있다.


align-self

align-self는 개별 아이템이 교차축에서 위치하는 곳을 설정하는 속성으로 align-items의 작은 버전이라고 볼 수 있다. align-items의 값들과 마찬가지로 stretch, flex-start, flex-end, center, baseline이 값이 될 수 있다.


지금부터는 반응형 웹페이지를 만들고 유연하게 요소들을 컨트롤하기에 필요한 속성들을 알아볼 것이다. 그 이름들은 flex-grow,flex-shrink, flex-basis가 되겠다. 이 세 속성과 flex속성은 컨테이너가 아닌 개별 아이템들에 달아주는 속성들이다.


flex-basis

flex-basis는 flex 아이템의 기본 크기를 설정한다. (flex-direction이 row일 때는 너비, column일 때는 높이). 기본값 auto로 설정하면 해당 요소의 width값이 된다.

이는 min-width처럼 최소한의 기본 크기를 설정하려고 한다. 그러나 min-width와 같은 것은 아니다. 만약 min-width로 기본 크기로 설정한다면 창의 크기 변화에 상관없이 무조건 min-width로 설정된 값을 가지지만 flex-basis로 설정한다면 창의 크기가 줄어들 때 크기가 줄어든다.


flex-grow

flex-grow는 증가 비율을 나타내는 속성으로 0으로 지정되면 아무런 효과가 없지만 0 이상의 수로 지정한다면 다른 요소들의 flex-grow값과 비교하여 그 비율만큼 컨테이너 내에서 크기를 정한다. 만약 flex-basis가 지정되어 있는 상황이면 어떻게 될까? flex-basis의 크기는 제외하고 그 비율을 가지려고 한다.


flex-shrink

flex-shrink 속성은 플렉스박스에 flex-wrap: wrap 속성을 부여한 경우 적용되지 않는다. 요소들의 너비 합이 컨테이너의 너비를 넘어설 경우 컨테이너의 너비를 넘지 않고 각각 요소마다 어느 정도로 수축할 것인지 정할 수 있는 속성이다.

이는 flex-grow와 반대로 아이템이 flex-basis의 값보다 작아질 수 있는지를 결정한다. 기본값은 1로 되어있기 때문에 flex-basis보다 크기가 작아질 수 있다. 그러나 0으로 flex-shrink를 설정하면 고정 폭을 가질 수 있다.


flex

flex-grow, flex-shrink, flex-basis를 한 번에 쓸 수 있는 축약형 속성이다.

.item {
	flex: 1;
	/* flex-grow: 1; flex-shrink: 1; flex-basis: 0%; */
	flex: 1 1 auto;
	/* flex-grow: 1; flex-shrink: 1; flex-basis: auto; */
	flex: 1 500px;
	/* flex-grow: 1; flex-shrink: 1; flex-basis: 500px; */
}

출처 및 참고

https://developer.mozilla.org/ko/docs/Learn/CSS/CSS_layout/Flexbox

http://www.tcpschool.com/css/css3_expand_flexbox

https://studiomeal.com/archives/197

좋은 웹페이지 즐겨찾기