CSS3 Flexbox Layout

안녕하세요. 웹표준개발 1팀 홍파 옥영성입니다.

최근 마크업 업무중 자주 접하게 되는 이야기가 있습니다.
“화면 크기에 상관없이 영역 딱 정중앙에 있으면 됩니다”
“…..”
간단한 이야기지만 결코 간단하지만은 않다는 것을 우리 모두 알고 있죠.
오늘은 이런 이슈들을 비교적 손쉽게 해결 할 수 있는 새로운 CSS 레이아웃을 알아보겠습니다.

바로 CSS3 스펙에 새롭게 추가된 Flexbox (Flexible box) 레이아웃 모듈 입니다.

1. Flexible box layout의 정의

웹의 형태와 기기의 다양화에 따라 CSS3에 새롭게 추가된 속성으로,
기기 및 브라우저의 크기 변화에 따라서, 요소의 상대적 위치 및 크기도 유동적으로 일정하게 변화하는 레이아웃 모델입니다.

이 레이아웃 방법을 사용하면, 기존 방법과는 다르게 일정한 영역 내 요소들의

  • 자유로운 정렬
  • 크기, 공간의 적극적인 사용
  • 요소 위치 변경

과 같은 이슈들을 조금 더 손쉽게 해결할 수 있습니다.
기존의 display:block, inline-block 등과는 다른 새로운 개념이라고 할 수 있죠.

flexbox 레이아웃을 사용하려면 첫번째로, 부모요소(flex-container), 자식요소(flex-items)가 우선 정의되어야 합니다.
실제 하나씩 사용해보면서 알아보도록 하겠습니다.

2. Flexible box layout의 용어 정리

word.jpg
flex container
요소에 display:flex / display:inline-flex를 부여함에 따라 형성되는 박스 영역
결정된 flex container 자식요소들이 flex-items이 될 수 있습니다.
flex items
flex container의 자식 요소들.
실질적으로 flex layout 모델에 따라 배치됩니다.
main axis
flex item들이 정렬되는 기본방향을 의미합니다. 수평,수직 모두 새로 지정해줄 수 있습니다.
main start/ main end
flex item들이 시작/끝나는 지점을 의미합니다. main axis의 시작과 끝을 의미합니다.
cross axis
기본 방향(main axis)의 수직방향을 의미합니다. 기본 방향에 따라 정의됩니다.
cross start/cross end
cross axis의 시작과 끝을 의미합니다.

3. Flex container 속성 (부모에게 주는 속성)

단순히 하나의 요소가 있고, 그 요소에 display:flex 속성이 부여되면
해당 요소가 flex container가 됩니다.
flex container가 가지고 있는 자식요소들의 배열 방향을 지정해주고, 방향에 따라 정렬할 수도 있습니다.

한가지씩 살펴보도록 하겠습니다.

※ 이하 예제는 최신 크롬브라우저에서 정확히 확인가능합니다.

display

flex container를 만들어 봅시다.

display : flex
block 레벨의 flex container를 생성
display : inline-flex
inline 레벨의 flex container를 생성

blank.gif

flex-direction

flex container안의 자식들을 배열합시다.

flex-direction : row
기본 축을 가로로 지정하여 자식요소를 배열 (좌 -> 우)

blank.gif

flex-direction : row-reverse
row와 동일하나 반대방향으로 배열 (우 -> 좌)

blank.gif

flex-direction : column
기본 축을 세로로 지정하여 자식요소를 배열 (상 -> 하)

blank.gif

flex-direction : column-reverse
column과 동일하나 반대방향으로 배열 (하 -> 상)

justify-content

flex container의 자식들을 기본 축을 기준으로 정렬해봅시다.

justify-content : flex-start
main-start 기준 정렬

blank.gif

justify-content : flex-end
main-end 기준 정렬

blank.gif

justify-content : center
가운데 가로 정렬

blank.gif

justify-content : space-between
일정한 간격으로 양끝에 붙도록 균등 정렬

blank.gif

justify-content : space-around
일정한 간격으로 균등 정렬하되, 균등한 여백의 절반값이 양끝에 자동으로 들어감.

blank.gif
3.jpg

align-content

flex container의 자식들을 교차 축을 기준으로 정렬해보겠습니다.
*한줄의 자식들만 있는 경우에는 영향이 없다.

align-content : stretch
cross-start를 기준으로 여유 공간을 균등하게 분할한 여백을 가짐
align-content : flex-start
cross-start 기준 정렬
align-content : flex-end
cross-end 기준 정렬
align-content : center
가운데 가로 정렬
align-content : space-between
일정한 간격으로 양끝에 붙도록 균등 정렬
align-content : space-around
일정한 간격으로 균등 정렬하되, 균등한 여백의 절반값이 양끝에 자동으로 들어감.

4.jpg

 

align-item

flex container의 한행의 자식들을 세로정렬로 지정해보자.

align-items : stretch
flex-container의 높이에 꽉 차게 늘림

blank.gif

align-items : flex-start
cross-start 기준 정렬
align-items : flex-end
cross-end 기준 정렬
align-items : center
가운데 정렬
align-items : baseline
flex item 내부 inline 요소의 baseline 기준 정렬

blank.gif

5.jpg

 

flex-wrap

flex container안의 자식들을 줄바꿈 합시다.

flex-wrap : nowrap
줄바꿈 없이 한 줄에 배치

blank.gif

flex-wrap : wrap
줄바꿈

blank.gif

flex-wrap : wrap-reverse
줄바꿈이 되나, 반대방향으로 줄바꿈 (하 -> 상) 가로방향은 기본값과 동일

flex-flow

flex container안의 기본 축과 교차 축을 정의합시다.
flex-direction 속성과 flex-wrap 속성을 한번에 지정가능.

1.jpg

flex-flow : row
기본 축 가로. 줄바꿈 없이 한 줄에 배치(좌->우)
flex-flow : row wrap
기본 축 가로(좌->우), 여러 줄에 배치

blank.gif

 

flex-flow : row-reverse wrap
기본 축 가로(반대방향 : 우->좌), 여러 줄에 배치
flex-flow : row-reverse wrap-reverse
기본 축 가로(반대방향 : 우->좌) / 여러 줄에 배치(반대방향 : 하->상)
flex-flow : column wrap
기본 축 세로, 여러 줄에 배치

4. Flex items 속성 (자식에게 주는 속성)

이제까지 살펴보았던 속성은 부모요소 flex-container에 부여되는 속성입니다.
flex 속성이 부여된 부모요소의 자식에게 flex속성이 부여되면 자식요소들이 flex-item의 관계가 되는데요,
이 flex-item은 부모의 크기에 유동적인 크기를 가지게 할 수 있습니다.

flex-grow

flex item의 전체 폭이 flex container의 폭보다 작을 경우, flex item의 폭의 확대 비율을 지정하여 flex container 폭에 맞게 자동으로 크기 조절할 수 있습니다.

flex-grow : [n]
기본값 1, 0일 경우 원래의 크기를 유지합니다.

blank.gif

flex-shrink

flex item의 전체 폭이 flex container의 폭보다 클 경우, flex item 항목 폭의 축소 비율을 지정하여 flex container 폭에 맞게 자동으로 크기 조절해 봅시다.

flex-shrink : [n]
기본값 1, 0일 경우 원래의 크기를 유지합니다.

flex-basis

flex container 내에서 flex item을 배치할 때 그 기준 폭을 지정해 봅시다.

flex-basis : auto
기본값으로 크기는 유동적으로 지정됩니다.
flex-basis : width값
일반적인 block 요소의 width값과 동일

flex

앞선 3가지 속성을 별도로 사용할 수 있지만, 다른 css속성들과 마찬가지로 단축속성으로 지정할 수 있습니다.

flex-grow / flex-shrink / flex-basis를 한번에 지정해 봅시다.

2.jpg

flex : initial
= flex : 0 1 auto

blank.gif

flex : auto
= flex : 1 1 auto

blank.gif

flex : none
= flex : 0 0 auto

blank.gif

flex : [n]
= flex : [n] 1 0

사용예제

flex 속성을 응용해서, 부모 너비에 대해 1:2:3 의 비율을 가지는 레이아웃을 만들어봅시다.
실제 flexbox 레이아웃이 필요해서 사용하게 될 경우 flex:1, flex:2 와 같이 축약된 속성으로 사용하게 될 것 같습니다.

blank.gif

예제

대략적으로 flexbox 레이아웃이 작동하는 방식에 대해서 알아보았는데요, 구체적인 예제들을 통해 조금 더 이해해 보도록 하겠습니다.

버튼들의 크기가 일정한 탭메뉴

영역내 수직/수평 중앙정렬

blank.gif

UI내 빈공간을 모두 사용하기

blank.gif

바로 사용해볼만한 예제도 만들어보았는데요, 이쯤에서 한가지 짚고 넘어가야 할 부분이 있습니다.
실무에 곧바로 사용할 수 있는가? 하는 문제 입니다.

브라우저 지원

먼저 현재 지원 상황을 살펴보겠습니다. [브라우저 지원현황]
정리해보면,

  • 최신브라우저들이 모두 지원하지만, PC대응으로 직접 사용하기에는 제약이 많다. (IE)
  • 다만, 모바일 전용 페이지, 모바일 앱내 웹뷰 페이지, 하이브리드 앱내 등에서 충분히 활용할 수 있겠다.

한가지 중요한 점은, 새로운 속성으로 바뀌었지만 이전 속성을 버리고 교체된 것이 아니라
이전 속성 지원은 유지한 채 새로운 속성이 추가 된다는 것입니다. 즉, 함께 사용할 수 있는 거겠죠.

img_syntax.png
[출처: dev.opera.com]

코드 사용 예

환경:
ios, android 모바일 브라우저
페이지:
다루었던 코드 예제 중 영역 내 수직/수평 중앙 정렬

프로젝트의 현실적인 지원범위 내에서, 다음과 같이 사용해 볼 수 있겠습니다.

ex_code2.png

결론

CSS3 Flexbox 레이아웃 모듈은 초안공개 이후 지속적으로 수정,개선되어 왔습니다.
W3C CSS 모듈 스펙에 따르면 현재 LCWD(최종 작업 초안)상태 입니다.
CR(후보 권고안)이 되지 얼마 남지 않았다는 말이겠죠.
아직 권고안 까지 최종 확정되기엔 많은 시간이 남았지만,
앞서 살펴보았듯이 거의 모든 최신브라우저가 지원하고 있는 상황이고,
스펙자체가 크게 변경되거나 사라질 가능성은 그리 많지 않아보입니다.
실제 twitter와 같은 대규모 서비스에서도 flexbox 레이아웃을 지금 사용하고 있습니다. (트위터 모바일)
따라서, 프로젝트 및 서비스의 지원 범위에 맞추어 바로 사용해 볼 수 있지 않을까요?

지금까지 새로운 모듈인 flexbox 레이아웃들 통해 기존 까다롭던 이슈들을 조금 손쉽게 해결할 수 있음을 확인해보았습니다.
flexbox 레이아웃 뿐만 아니라 더 많은 새로운 방법들을 곧 맞이하게 될것 같은데요,
자료를 정리하다가 읽게된 새로운 도구를 다루는 방법에 대한 이야기를 끝으로 flexbox에 대한 이야기를 마치겠습니다.
감사합니다.

“The hardest thing to learn about new tools
is not how to use them, but when to use them.”
– Stephen Hay

참고자료

작성자: 웹표준개발1팀 홍나영, 옥영성, 서재영, 김효정