오늘은 흔히 flex 또는 flexible 박스 모델이라고 부르는 CSS Flexsible box layout module level 1(Candidate Recommendation) 명세를 설명해 보려고 합니다. 아직 표준 후보 단계이지만 현존하는 최신 브라우저에 flexible box layout module은 이미 구현되어 있습니다.
기존에 우리가 사용하던 레이아웃 기법은 display
, float
, position
으로써 컬럼 레이아웃을 표현하는데 한계가 있고 구현 방법이 복잡한 문제가 있었는데요. flexible(신축성 있는, 유연한) 박스 모델의 장점을 한 마디로 표현하면 “복잡한 계산 없이 박스의 크기와 순서를 유연하게 배치할 수 있다.” 라고 정리할 수 있습니다. 쉬운 예를 들면 컬럼의 한 쪽은 고정하고 다른 한 쪽을 가변폭으로 처리하고 싶을 때 유용하지만 그것 이상의 편의를 제공합니다. 어떤 속성과 값을 통해 무엇을 할 수 있는지 설명해 보겠습니다.
flex 박스 모델은 tr
/ td
개념와 유사합니다. flex 박스는 flex container(부모, 마치 tr
)와 flex item(자식, 마치 td
)으로 이루어 집니다. flex container 요소에 display
속성의 값을 flex
또는 inline-flex
라고 선언하면 해당 요소는 flex container가 되고 자식 요소는 자동으로 flex item이 되어 flex 박스로 렌더링하기 시작합니다.
flex container는 flex item의 면적, 방향, 정렬을 결정하는 컨테이너 입니다. flex container 요소에 display
속성의 값으로 inline-flex
를 선언하면 인라인 수준의 flex container를 생성하고, flex
값을 선언하면 블럭 수준의 flex container를 생성합니다. inline-flex
상태의 컨테이너는 inline-block
박스와 같은 형태로 표시합니다.
flex item은 컨테이너 내부에 형성된 free space(남거나 모자라는 공간, margin
과 유사한 개념이지만 margin
은 아님)를 팽창지수 또는 수축지수 값에 따라 형제들이 서로 나누어 갖습니다. flex container에 inline-flex
또는 flex
값을 선언하면 자식 요소들은 자동으로 flex item이 됩니다. flex item의 기본적인 스타일(User Agent 기본값)은 다음과 같습니다. 기본 스타일( flex-grow:0; flex-shrink:1; flex-basis:auto; flex-direction:row; flex-wrap:nowrap;
)은 개발자가 변경할 수 있으며, 단축 속성( flex
)을 사용할 때 값이 자동으로 재설정(flex item의 단축 속성 ‘flex’ 참고)되기도 합니다.
flex-grow:0
)flex-shrink:1
)flex-basis:auto
)flex-derection:row
)flex-wrap:nowrap
)그 밖에 이런 특징도 있습니다.
float
속성은 무시합니다.position:absolute|fixed
속성이 부여되면 flex item에서 빠지게 됩니다.margin
을 중첩하지 않습니다.margin
/ padding
의 값으로 상대 단위(%)를 사용하지 않는 것이 좋습니다.flex container의 자손은 flex item이 되지 않습니다.
flex item은 flex-grow
(팽창지수), flex-shrink
(수축지수), flex-basis
(기준 사이즈) 속성과 이것들의 단축 속성인 flex
속성으로 박스의 팽창, 수축, 기준 사이즈를 제어할 수 있습니다. W3C 명세는 flex
단축 속성( flex : none | [<flex-grow> <flex-shrink>? || <flex-basis>]
)으로 제어하는 것을 권장합니다. 단축 속성은 명시하지 않은 값을 일반적인 용도에 맞게 재설정하기 때문입니다. 단축 속성 선언 시 재설정되는 값에 대한 설명은 flex item의 단축 속성 ‘flex’를 참고하세요. 참고: CSS 명세에서 바 |
는 분리된 값들 중 반드시 ‘하나’를 선언해야 한다는 의미입니다. 더블 바 ||
는 분리된 값들 중 ‘하나 또는 그 이상’을 선언할 수 있다는 의미입니다. 물음표 ?
는 ‘생략하거나 또는 한 번만 선언’해야 한다는 의미입니다.
flex-grow
속성.0
또는 1
값을 선언.flex
사용 시 flex-grow
값을 생략하면 값은 초기 값은 1
으로 다시 설정 됨.flex-grow
속성의 기본값은 0
이기 때문에 flex item은 기본적으로 팽창하지 않습니다. flex-grow
의 값이 0
이 아닌 경우에는 컨테이너 내부에 형성된 빈 공간(free space)을 팽창지수( flex-grow
)에 따라 flex item에 반영하여 남은 공간을 채우게 됩니다. 공간이 남는 경우에는 flex-grow
속성에 의해 팽창하지만, 공간이 남지 않는 경우에는 아무리 값을 올려도 컨테이너의 너비 이상으로 팽창하지 않습니다. max-width
속성을 선언했다면 이 값을 초과하여 팽창하지 않습니다.
flex-shrink
속성.0
또는 1
값을 선언.flex
사용 시 flex-shrink
값을 생략해도 초기 값은 여전히 1
이 된다.flex-shrink
속성의 기본값은 1
이기 때문에 flex item은 기본적으로 수축합니다. flex-shrink
값이 0
인 경우 flex item의 너비가 컨테이너를 초과 해도 수축하지 않습니다. 한편 flex-shrink
값이 0
이 아닌 경우에는 flex item이 컨테이너를 초과했을 때 넘치는 공간(이 때 음수 free space 발생)의 크기를 기준으로 수축지수( flex-shrink
)에 따라 수축하게 됩니다. 컨테이너를 초과해서 공간이 모자라는 경우에는 flex-shrink
속성에 의해 수축하지만, 공간이 모자라지 않는 경우에는 아무리 값을 올려도 수축하지 않습니다. min-width
속성을 선언했다면 이 값 미만으로 수축하지 않습니다.
flex-basis
속성.flex-basis
속성은 flex item 요소가 flex-grow
또는 flex-shrink
속성에 의해 팽창/수축하기 이전의 기준 크기를 명시하는 속성입니다. flex item에 width/height
값을 명시하는 것은 flex-basis
값을 선언하는 것과 결과적으로 동일합니다. flex item의 팽창 또는 수축은 width/height
값 또는 flex-basis
에 선언한 값을 기준으로 free space(빈 공간) 값을 구하게 되고, free space 값은 팽창/수축 지수를 통해 flex item의 크기에 영향을 미치게 되므로 flex-basis
(또는 width/height
) 값을 가능하다면 명시적으로 선언하는 것이 좋습니다. 동일한 flex item에 width/height
값과 flex-basis
값을 동시 선언하는 경우 flex-basis
값은 width
값을 덮어 쓰기 때문에 코드를 간결하게 작성하려면 width/height
값을 선언하는 것보다 flex-basis
값을 선언하는 것을 권장합니다. content
값은 선언 불가능한 값입니다. content
값을 적용하려면 auto
값을 선언하고 width/height
속성을 사용하지 않아야 합니다.
flex
.flex
속성은 flex-grow
, flex-shrink
, flex-basis
속성의 값을 하나의 속성값으로 작성할 수 있는 단축 속성입니다. flex item 요소에 flex
와 관련 있는 아무런 속성도 선언하지 않은 경우 flex-grow:0; flex-shrink:1; flex-basis:auto;
다시 말하면 flex:0 1 auto;
상태가 됩니다. 세 가지 속성을 모두 선언할 수도 있지만 하나만 선언하고 다른 값을 생략할 수도 있는데요. 생략한 속성의 값은 자동으로 재설정 됩니다.
flex
단축 속성**은 아래와 같이 다양한 형태로 선언할 수 있습니다. 생략한 일부 속성의 값은 flex item에 아무런 속성도 선언하지 않았을 때의 값 flex:0 1 auto;
와도 다르고 flex:none;
을 선언했을 때의 값 flex:0 0 auto;
와도 다르다는 점에 유의하세요.
flex: none;
flex-grow:0; flex-shrink:0; flex-basis:auto;
상태가 된다.flex: <flex-grow>
flex-shrink:1; flex-basis:0;
상태가 된다.flex: <flex-basis>
flex-grow:1; flex-shrink:1;
상태가 된다.flex: <flex-grow> <flex-shrink>
flex-basis:0;
상태가 된다.flex: <flex-grow> <flex-basis>
flex-shrink:1;
상태가 된다.flex: <flex-grow> <flex-shrink> <flex-basis>