[출처] http://thrillfighter.tistory.com/489
지원브라우저는 다음과 같다. 모바일에서만 사용한다면 사용해도 유용한 정보이다.
기존의 웹페이지를 만들 때 사용하던 올드한 레이아웃 제작방법을 개선하고자 flexbox 가 생겨났다.flex는 flexible의 준말로 유동적인 레이아웃을 손쉽게 만들 수 있다는 의미를 가진다.기본 컨셉은 아주 명확하기 때문에 기존의 레이아웃을 만드는데 사용하던 table 태그나 position 또는 float 속성을 사용하는 방법의 복잡함을 고수할 필요가 없어졌다.다만 생각보다 다양한 속성들이 있어서 정리할 필요는 있다. 이 속성을 모두 사용할 필요는 없으므로 대략적인 이해만 해 둔 후에 필요할 때마다 참고하여 레이아웃을 만들면 될 것이다.
flexbox의 기본 컨셉
container와 item들이 부모와 자식관계일 때 container에 display : flex; 속성을 줌으로서 다음과 같은 모습의 flexbox 레이아웃으로 바뀐다.
다음은 display:flex; 속성을 줄 때 브라우저 상에서 레이아웃이 어떻게 바뀌는지를 보여주는 그림이다.
이렇게 flexbox 레이아웃으로 바뀐 후 부터는 flex container와 flex item 각각에 flex에 관련된 속성을 줄 수 있는데 각각을 구분하여 각각에 어떤 속성을 적용할 수 있고 어떤 효과가 있는지 알아보도록 하겠다.
flex container 속성들 정리
.container {
display : flex; /* inline-flex */
}
앞에서 설명한 속성으로 flex 레이아웃을 설정하기 위해 기본적으로 있어야 하는 속성이다. 속성 적용 후에 자식 요소들의 배치가 inline화(한줄에 배치) 되었음을 기억하자. 주의할 점은 이 속성은 직계(direct) 자손에게만 적용된다는 것이다.
container 클래스의 직계 자손들은 flexbox 레이아웃이 적용되어 가로(inline)로 한줄 안에 배치되었으나 container 클래스의 첫 번째 직계자손의 자손은 적용되지 않고 세로로 배치되었다. (div 태그는 display : block; 이 기본 속성이기 때문이다.)
따라서 다음 코드를 추가하여 flexbox 모든 자식에게 레이아웃을 적용시킬 수 있다.
display : inline-flex; 속성을 주면 container 영역이 item에 맞게 줄어든다.
flex-direction
.container {
display : flex;
flex-direction : row; /* row-reverse, column, column-reverse */
}
container 안에서 item들의 정렬과 배치 방향을 설정하는 속성이다.
flex-direction이 row면 container 내부에서 왼쪽 정렬, 왼쪽부터 아이템이 행방향으로 순서대로 배치된다.
flex-direction이 row-reverse면 container 내부에서 오른쪽 정렬, 오른쪽부터 아이템이 행방향으로 순서대로 배치된다.
container 클래스에 height 속성을 다음과 같이 넉넉히 잡고 다음 속성들을 줘보자.
flex-direction이 column이면 아이템들은 각각 한줄을 모두 차지하며 block 속성값을 갖는 것 처럼 열방향으로 배치된다.
flex-direction이 column-reverse면 container의 아래쪽 부터 위쪽으로 채워지면서 아이템 배치순서가 아래에서 위쪽으로 바뀐다.
※ 참고 : container를 display : inline-flex; 속성으로 바꾸면 위 속성들이 어떻게 동작하는지 확인하도록 하자.
flex-wrap
.container {
display : flex;
flex-wrap : nowrap; /* wrap, wrap-reverse */
}
item들의 너비의 합이 container의 너비(현재 브라우저 창의 너비)를 초과할 때 어떻게 처리할 지를 결정하는 속성이다. 그냥 줄바꿈 속성이라고 생각해도 된다.
nowrap 은 기본값으로 브라우저의 너비를 초과해도 상관없이 아이템들이 한 줄로 표시된다.
wrap 은 브라우저의 너비를 초과한 아이템들을 줄 바꿈을 하여 다음 줄로 넘긴다.
wrap-reverse는 wrap과 같지만 아래에서 위쪽으로 배치한다.
반응형 웹에서 PC와 같은 환경에서는 메뉴가 사이드에 표시되지만 모바일 환경에서는 아래로 길게 늘어뜨려지는 경우를 본 적이 있을 것이다. 이런 것은 이 속성으로 아주 간단히 표현할 수 있다.
flex-flow
.container {
display : flex;
flex-flow : row wrap; /* flex-direction과 flex-wrap의 조합 */
}
flex-flow는 바로 앞의 두 속성을 같이 설정할 수 있는 약식 표현 속성이다. 이런 약식표현으로 border가 있음을 우리는 알고 있으므로 쉽게 이해할 수 있다.
justify-content
.container {
display : flex;
justify-content : flex-start; /* flex-end, center, space-between, space-around */
}
item과 container 간에 수평방향으로 여백을 두는 방식을 지정한다.
이 속성은 container의 display 속성이 inline-flex 라면 소용없는 속성이다. 왜냐면 inline-flex 속성을 주면 item과 container 간에 여백이 없어지기 때문이다. 어렵지 않은 속성이므로 위 그림으로 설명을 대신한다.
align-items
.container {
display : flex;
height : 100px;
align-item : flex-start; /* flex-end, center, baseline, stretch */
}
justify-content 속성이 수평 방향으로 여백을 주는 방식을 설정하는 속성이라면 align-items는 수직방향으로 item과 container 간에 여백을 주는 방식을 설정한다. 이 속성의 정확한 이해를 위해서 height 속성을 넉넉히 준 후 실험하도록 한다.
이 속성들이 어떻게 동작하는지는 그림만으로도 충분히 이해할 수 있을 것이다.
속성값 baseline은 아래 그림을 보자.
속성값이 baseline을 이해하기 위해 font-size를 달리 해 보았다. 보시다시피 폰트의 baseline을 기준으로 정렬된다. 왼쪽에 flex-start가 정렬되는 방식과 비교하면 쉽게 이해할 수 있을 것이다.
align-content
.container {
display : flex;
flex-wrap : wrap;
align-content : flex-start; /* flex-end, center, space-between, space-around, stretch */
}
아이템들을 한 줄에 다 표시할 수 없어서 다음줄로 넘김이 발생했을 때 줄 사이에 여백을 결정하는 방식을 설정한다. 따라서 이 속성은 flex-wrap : wrap; 속성이 설정되어 있어야 제대로 동작한다.
justify-content가 수평방향으로 여백을 설정한다면 align-content는 수직방향으로 여백을 설정한다. align-item이 item과 container 간에 여백을 설정하는 것이라면 align-content는 수직방향으로 item들 사이의 여백과 item과 container 사이의 여백을 설정한다. 여백이 정해지는 방향만 다르지 방식은 동일하다.
살펴본 속성들이 많기는 하지만 꽤 직관적이기 때문에 이해하기는 쉽다. 필요할 때마다 그때 그때 참조해서 사용하면 된다.
flex item 속성들 정리
order
.item {
order : 1; /* 속성값은 숫자 */
}
order 속성은 아이템이 배치될 순서를 지정한다. 속성값은 숫자며 값이 작을수록 먼저 배치된다.
order 값이 -2로 가장 작은 item2가 제일 먼저 배치되고 order 값이 100으로 가장 큰 item1이 가장 마지막에 배치되었다.
flex-grow
.item {
flex-grow : 1; /* 속성값은 숫자 */
}
flex-grow는 container에 여분의 여백이 있을 때 동작하는 속성이다. 여분의 여백이 있다면 flex-grow에 설정된 비율만큼 분배되도록 동작된다. 따라서 브라우저를 가로방향으로 늘리게 되면 flex-grow에 설정된 비율만큼씩 증가되는 것을 볼 수 있을 것이다.
4개의 item에 flex-grow를 설정해 놨다. 현재 브라우저의 너비가 여분의 여유공간이 없으므로 item들에 flex-grow가 적용되지 않은 상태다. 브라우저 창을 가로방향으로 서서히 늘려보면 container에 여백이 생기는 순간부터 이 여백이 각각의 item에게 flex-grow에 설정한 비율만큼씩 분배되는 것을 알 수 있다.
하지만 늘어난 브라우저를 다시 줄여보면 줄어드는 비율도 위와 같다. 따라서 flex-grow는 늘어나는 비율 뿐 아니라 줄어드는 비율이기도 하다.
flex-basis
.item {
flex-basis : 100px;
}
flex-basis는 item의 기본 너비를 설정한다.
그런데 이 속성을 정하면 디폴트로 flex-shrink 속성이 붙는다. 그리고 flex-shrink는 item마다 줄어드는 비율을 설정하는 속성이다. flex-basis에서 설정한 너비보다 더 줄이면 flex-shrink 속성에 설정한 비율로 줄어드는 것을 볼 수 있다.
위 그림에서 브라우저의 창을 줄이다가 container와 item의 여백이 없어진 이후에도 창을 더 줄이면 item들은 flex-basis에서 설정한 100px 이하로 줄어들 것이다. 이 때부터 flex-shrink에서 설정한 비율만큼 줄어드는데 현재 디폴트로 네 개의 아이템의 flex-shrink의 값은 동일하다. 즉 동일한 비율로 줄어드는 것을 볼 수 있다. (각각 1/4, 1/4, 1/4, 1/4 의 비율로)
주의할 점은 flex-basis를 설정해도 flex-grow는 디폴트로 주어지지 않는다는 것이다. 그래서 위 그림에서 각 item들이 100px 이상 늘어나지 않는 것이다. 만약 flex-grow를 주면 어떻게 되는지는 아래 flex-shrink 속성의 설명을 참고하도록 하자.
flex-shrink
.item {
flex-shrink : 4;
}
flex-shrink는 item이 줄어드는 비율을 설정한다. flex-basis를 설정했다면 이 값을 경계로 item의 너비가 flex-basis에서 설정한 값보다 클 때는 flex-grow가 동작하고 item의 너비가 flex-basis에서 설정한 값 보다 작을 때는 flex-shrink가 동작한다.
따라서 위와 같이 설정했다면 flex-grow 속성으로 인해 브라우저를 아무리 늘려도 container와 item 사이에 여분의 여백은 생기지 않는다.
지금까지 다양한 flexbox 레이아웃에 관한 속성들을 살펴보았다.