1 of 96

CSS flex

you must know.

레진엔터테인먼트

정 찬 명

2 of 96

3 of 96

브라우저 호환성

  • IE 9 이하 #지원안함
  • IE 10 #2012명세 #버그많음 #-ms-
  • IE 11 #버그많음 #min-/max-버그
  • Android 4.3 이하 #2009명세 #wrap(x) #order(x) #-webkit-

CSS flex 문제 해결:

http://naradesign.net/wp/2017/05/19/2543/

https://github.com/philipwalton/flexbugs

4 of 96

플렉스 실무 적용 사례

5 of 96

박스 크기 자동 분배(마치 테이블)

6 of 96

양쪽 끝 정렬(공간 자동 분배)

Auto margin(X) => Free space(O)

7 of 96

배치 순서 바꾸기

8 of 96

흘러 내리기(마치 인라인 박스)

Android 4.3 이하(X)

9 of 96

교차 축 정렬

10 of 96

FAQ

Q:

테이블 마크업으로 처리하면 다 되던 일 아닙니까?

A:

네, 맞습니다. 하지만 테이블은...

11 of 96

플렉스 개요

12 of 96

flex overview

Flex layout is superficially similar to block layout. It lacks many of the more complex text- or document-centric properties that can be used in block layout, such as floats and columns. In return it gains simple and powerful tools for distributing space and aligning content in ways that web apps and complex web pages often need. The contents of a flex container:

https://www.w3.org/TR/css-flexbox-1/#overview

이 페이지는 나중에 보세요!

13 of 96

플렉스 개요

플렉스 레이아웃은 표면적으로 블럭 레이아웃과 유사하다.

그러나 블럭 레이아웃에서 사용할 수 있는 다양한 속성이 부족했기 때문에 공간을 분배하고 내용을 정렬하기 위한 수단으로 플렉스 레이아웃이 등장했다.

https://www.w3.org/TR/css-flexbox-1/#overview

이 페이지는 나중에 보세요!

14 of 96

flex overview

  • can be laid out in any flow direction (leftwards, rightwards, downwards, or even upwards!)
  • can have their display order reversed or rearranged at the style layer (i.e., visual order can be independent of source and speech order)
  • can be laid out linearly along a single (main) axis or wrapped into multiple lines along a secondary (cross) axis
  • can “flex” their sizes to respond to the available space
  • can be aligned with respect to their container or each other on the secondary (cross)
  • can be dynamically collapsed or uncollapsed along the main axis while preserving the container’s cross size

https://www.w3.org/TR/css-flexbox-1/#overview

이 페이지는 나중에 보세요!

15 of 96

플렉스 개요

  • 어떤 흐름 방향이라도 가능하다.(왼쪽, 오른쪽, 아래, 위)
  • CSS를 통해 시 순서를 뒤집거나 다시 정렬하는 것이 가능하다.(시각적 표시 순서는 HTML 순서와 독립적이다.)
  • 진행축을 따라 한 줄 또는 교차축을 따라 여러 줄로 감싸면서 선형 배치할 수 있다.
  • 용 가능한 공간에 반응하도록 크기를 조절할 수 있다.
  • 컨테이너에 맞추거나 또는 교차축에 맞춤 정렬할 수 있다.
  • 진행축을 따라 동적으로 접을 수 있다.

https://www.w3.org/TR/css-flexbox-1/#overview

이 페이지는 나중에 보세요!

16 of 96

TL;DR

플렉스는

박스의

크기, 방향, 순서, 정렬, 간격

제어하는

새로운 박스 모델.

17 of 96

TL;DR

플렉스는

테이블 박스모델 보다

더 나긋나긋하고

더 쓰임새 많은

새로운 박스 모델.

18 of 96

플렉스 용어

  • flex container
  • flex item
  • free space
  • main axis
  • cross axis

19 of 96

flexible box model

진행축이 수평인 경우 플렉스 아이템이 흐르는 방향

1

2

플렉스 컨테이너

3

플렉스 아이템

프리 스페이스

진행축

교차축

20 of 96

flexible box model

진행축이 수직인 경우 플렉스 아이템이 흐르는 방향

1

3

플렉스 컨테이너

2

플렉스 아이템

프리 스페이스

진행축

교차축

21 of 96

플렉스 컨테이너 flex container

'display' 속성 값이

'flex' 또는 'inline-flex'인 박스.

내부에 흐르는 자식 콘텐츠(엘리먼트, 텍스트 노드)는 저절로 플렉스 아이템이 된다.

22 of 96

플렉스 컨테이너 flex container

플렉스 컨테이너에만 적용 가능한 속성들이 있다.

.flex-container {

display: flex; /* 컨테이너 선언 */

flex-direction: row; /* 흐름 방향 */

flex-wrap: nowrap; /* 줄 바꿈 */

justify-content: flex-start; /* 진행축 정렬 */

align-items: stretch; /* 교차축 정렬 */

align-content: stretch; /* 여러줄 교차축 정렬 */

}

이 페이지는 나중에 보세요!

23 of 96

플렉스 아이템 flex item

플렉스 컨테이너 내부에서 흐르는 자식 박스(엘리먼트, 텍스트 노드)를 플렉스 아이템이라고 부른다.

플렉스 박스 모델에 따라 배치된다.

24 of 96

플렉스 아이템 flex item

플렉스 아이템에만 적용 가능한 속성이 있다.

.flex-item {

flex-grow: 0; /* 팽창지수 */

flex-shrink: 1; /* 수축지수 */

flex-basis: auto; /* 기준크기 */

align-self: auto; /* 독립적 교차축 정렬 */

order: 0; /* 배치순서 */

}

이 페이지는 나중에 보세요!

25 of 96

프리 스페이스 free space

플렉스 컨테이너로부터 플렉스 아이템의 크기(flex-basis, width, height), padding, border, margin을 제외하고 남은 공간을 프리 스페이스라고 부른다.

'0, 양수, 음수' 프리 스페이스가 발생할 수 있다.

프리 스페이스는 플렉스 아이템의 팽창 지수(flex-grow)와 수축 지수(flex-shrink)를 이용하여 플렉스 아이템으로 분배할 수 있다.

이 장표 이후 'FS''프리 스페이스'를 의미한다.

중요한 개념!

26 of 96

진행축 main axis

플렉스 아이템 배치 방향으로써 플렉스 컨테이너에 flex-direction 속성을 적용하여 설정할 수 있다.

진행축(flex-direction)의 초기값은 row이며 row-reverse, column, column-reverse 값을 적용할 수 있다.

27 of 96

교차축 cross axis

플렉스 아이템 배치 방향과 직각(90도)으로 교차하는 방향으로써 flex-direction 값의 직각 방향이다.

진행축의 방향에 따라 교차축이 달라지기 때문에 교차축은 이 될 수도 있고 이 될 수도 있다.

align-* 속성의 기준이 되는 축이다.

28 of 96

플렉스 컨테이너

display : flex;

display : inline-flex;

29 of 96

.container { display : flex }

.container

.item

.item

.container

.item

.item

사용 빈도 높음!

30 of 96

.container { display : inline-flex }

.container

.item

.item

.container

.item

.item

31 of 96

플렉스 아이템의 팽창과 수축

flex-grow : 0;

flex-shrink : 1;

flex-basis : auto;

flex : 0 1 auto;

32 of 96

flex-grow:

양수 FS 발생 시 플렉스 아이템의 팽창을 제어.

  • 값: <number> � // 음수 사용 불가. 보통 '0' 또는 '1' 사용.
  • 초기값: 0 � // 단축 속성에서 생략하면 '1'이 됨.
  • 적용: 플렉스 아이템

33 of 96

.item { flex-grow: 0 }

초기값은 '0' 으로써 팽창하지 않는다.

플렉스 컨테이너에 양수 FS가 발생했다.

.item

.item

34 of 96

.item { flex-grow: 1 }

양수 FS 발생 시 'flex-grow:1'을 적용하면 플렉스 아이템 균등 팽창.

.item (50%)

.item (50%)

사용 빈도 높음!

35 of 96

.item1 { flex-grow: 1 }

.item2 { flex-grow: 2 }

플렉스 아이템마다 팽창 비율을 다르게 처리할 수 있다.

.item1 �(33.33%)

.item2 �(66.66%)

36 of 96

flex-shrink:

음수 FS 발생 시 플렉스 아이템의 수축을 제어.

  • 값: <number> � // 음수 사용 불가. 보통 '0' 또는 '1' 사용.
  • 초기값: 1 � // 단축 속성에서 생략해도 '1'이 됨.
  • 적용: 플렉스 아이템

37 of 96

.item { flex-shrink: 0 }

음수 FS가 발생했다.

'flex-shrink:0'을 적용하면 음수 FS가 발생 하더라도 수축하지 않음.

.item (100%)

.item (100%)

38 of 96

.item { flex-shrink: 1 }

초기값은 '1' 으로써 음수 FS 발생 시 균등 수축.

.item (50%)

.item (50%)

사용 빈도 높음!

39 of 96

.item1 { flex-shrink: 1 }

.item2 { flex-shrink: 2 }

플렉스 아이템마다 수축 비율을 다르게 처리할 수 있다.

.item1 �(66.66%)

.item2� (33.33%)

40 of 96

flex-basis:

플렉스 아이템의 본 크기를 설정함으로써 FS 초기값에 영향을 준다.

  • 값: content | <width> � // 팽창/수축하기 이전의 기본 크기.
  • 초기값: auto � // content 또는 <width> 값이 적용됨.� // 단축 속성에서 생략하면 초기값이 '0' 이 된다.
  • 적용: 플렉스 아이템

41 of 96

.item { flex-basis: auto }

content 크기가 플렉스 아이템의 기본 크기.

플렉스 컨테이너에 남은 공간이 양수 FS가 된다.

// 'content' 라는 값을 직접 선언할 수는 없다. 'auto'를 선언해야 한다.

.item

.item

42 of 96

.item { flex-basis: 30% }

너비 30% 크기가 플렉스 아이템의 기본 크기.

플렉스 컨테이너에 남은 공간(40%)이 양수 FS가 된다.

.item (30%)

.item (30%)

43 of 96

.item { flex-basis: 60% }

너비 60% 크기가 플렉스 아이템의 기본 크기.

플렉스 컨테이너를 초과하는 공간(-20%)이 음수 FS가 된다.

.item (60%)

.item (60%)

44 of 96

.item { flex-basis: 0 }

플렉스 아이템의 기본 크기가 '0' 이므로 플렉스 컨테이너의 크기 100%가 양수 FS가 되었다.

사용 빈도 높음!

45 of 96

flex:

플렉스 아이템의 '창, 수축, 기본 크기' 단축.

  • 값: none | [<flex-grow> <flex-shrink>? || <flex-basis>] // | 반드시 하나, ? 생략하거나 한 번, || 하나 또는 그 이상.
  • 초기값: 0 1 auto � // 생략한 속성의 값은 재설정 된다.
  • 적용: 플렉스 아이템

46 of 96

.item { flex: 1 }

==

.item { flex: 1 1 0 }

flex-shrink 초기값은 변함없이 '1' 이다. flex-basis 초기값이 'auto' 에서 '0' 으로 변경됐다.

사용 빈도 높음!

47 of 96

.item { flex: initial }

==

.item { flex: 0 1 auto }

플렉스 아이템에 아무것도 선언하지 않았을 때의 초기값과 같다. 굳이 이렇게 선언할 필요는 없다.

사용 빈도 낮음.

48 of 96

.item { flex: none }

==

.item { flex: 0 0 auto }

플렉스 박스 모델을 사용하지 않기 위해 값을 덮어 쓸 필요가 있는 경우 이렇게 쓸 수 있다. 굳이...

사용 빈도 낮음.

49 of 96

.item { flex: auto }

==

.item { flex: 1 1 auto }

flex-grow 초기값이 '0' 에서 '1' 으로 변경 됐다. flex-shrink 초기값은 변함없이 '1' 이다.

사용 빈도 낮음.

50 of 96

.item { flex: 1 1 }

==

.item { flex: 1 1 0 }

flex-basis 초기값이 'auto' 에서 '0' 으로 변경됐다.

사용 빈도 낮음.

51 of 96

.item { flex: 1 0% }

==

.item { flex: 1 1 0% }

flex-shrink 초기값은 변함없이 '1' 이다.

사용 빈도 낮음.

52 of 96

.item { flex: 0% }

==

.item { flex: 1 1 0% }

flex-grow 초기값이 '0' 에서 '1' 으로 변경 됐다. flex-shrink 초기값은 변함없이 '1' 이다.

사용 빈도 낮음.

53 of 96

플렉스 아이템의 방향과 순서

flex-direction : row;

flex-wrap : nowrap;

flex-flow : row nowrap;

order : 0;

54 of 96

flex-direction:

플렉스 아이템의 행 방향.

  • 값: row | row-reverse | column | column-reverse
  • 초기값: row
  • 적용: 플렉스 컨테이너

55 of 96

.container { flex-direction: row }

사용 빈도 높음!

56 of 96

.container { flex-direction: row-reverse }

사용 빈도 낮음.

57 of 96

.container { flex-direction: column }

사용 빈도 높음!

58 of 96

.container { flex-direction: column-reverse }

사용 빈도 낮음.

59 of 96

flex-wrap:

플렉스 아이템의 줄 바꿈.

  • 값: nowrap | wrap | wrap-reverse
  • 초기값: nowrap
  • 적용: 플렉스 컨테이너

#Android 4.3 이하(X)

60 of 96

.container { flex-wrap: nowrap }

사용 빈도 낮음.

61 of 96

.container { flex-wrap: wrap }

사용 빈도 높음!

62 of 96

.container { flex-wrap: wrap-reverse }

사용 빈도 낮음.

63 of 96

flex-flow:

플렉스 아이템의 행 방향줄 바꿈 단축.

  • 값: <flex-direction> || <flex-wrap>
  • 초기값: row nowrap
  • 적용: 플렉스 컨테이너

64 of 96

.container { flex-flow: row nowrap }

사용 빈도 낮음.

65 of 96

.container { flex-flow: row wrap }

사용 빈도 높음!

66 of 96

order:

플렉스 아이템의 치 순서.

  • 값: <integer> // '0, 양의 정수, 음의 정수'
  • 초기값: 0
  • 적용: 플렉스 아이템

#Android 4.3 이하(X)

67 of 96

.item { order: 0 }

사용 빈도 낮음.

68 of 96

.item:first-child { order: 1 }

사용 빈도 낮음.

69 of 96

.item:last-child { order: -1 }

사용 빈도 낮음.

70 of 96

플렉스 아이템의 정렬과 간격

justify-content : flex-start;

align-items : stretch;

align-self : auto;

align-content : stretch;

71 of 96

justify-content:

플렉스 아이템의 진행축 정렬.

  • 값: flex-start | flex-end | center | space-between | space-around
  • 초기값: flex-start
  • 적용: 플렉스 컨테이너

72 of 96

.container { justify-content: flex-start }

사용 빈도 높음!

73 of 96

.container { justify-content: flex-end }

사용 빈도 높음!

74 of 96

.container { justify-content: center }

사용 빈도 높음!

75 of 96

.container { justify-content: space-around }

사용 빈도 낮음.

76 of 96

.container { justify-content: space-between }

사용 빈도 높음!

77 of 96

align-items:

플렉스 아이템이 한 줄일 때 교차축 정렬.

  • 값: flex-start | flex-end | center | baseline | stretch
  • 초기값: stretch // 아이템을 교차축으로 잡아 늘림.
  • 적용: 플렉스 컨테이너

78 of 96

.container { align-items: stretch }

사용 빈도 높음!

79 of 96

.container { align-items: baseline }

사용 빈도 낮음.

80 of 96

.container { align-items: center }

사용 빈도 높음!

81 of 96

.container { align-items: flex-start }

사용 빈도 높음!

82 of 96

.container { align-items: flex-end }

사용 빈도 낮음.

83 of 96

align-self:

플렉스 아이템의 독립교차축 정렬.

  • 값: auto | flex-start | flex-end | center | baseline | stretch
  • 초기값: auto // 컨테이너의 align-items 값을 상속 받음.
  • 적용: 플렉스 아이템

84 of 96

.item:first-child { align-self: flex-start }

사용 빈도 낮음.

85 of 96

.item:first-child { align-self: center }

사용 빈도 낮음.

86 of 96

.item:first-child { align-self: flex-end }

사용 빈도 낮음.

87 of 96

align-content:

플렉스 아이템의 러 줄 교차축 정렬과 간격.

  • 값: flex-start | flex-end | center | space-between | space-around | stretch
  • 초기값: stretch // 줄 간격을 교차축으로 균등하늘림.
  • 적용: 여러 플렉스 컨테이너

88 of 96

.container { align-content: stretch }

사용 빈도 높음!

89 of 96

.container { align-content: center }

사용 빈도 높음!

90 of 96

.container { align-content: flex-start }

사용 빈도 높음!

91 of 96

.container { align-content: flex-end }

사용 빈도 낮음.

92 of 96

.container { align-content: space-around }

사용 빈도 낮음.

93 of 96

.container { align-content: space-between }

사용 빈도 낮음.

94 of 96

flexible 박스모델 스터디 총평

  • flex-grow, flex-shrink, flex-basis, flex 속성의 명세를 이해하는 것이 가장 어렵지만 중요한 포인트.
  • 그 밖의 속성들은 하나씩 놓고 보면 어렵지 않으나 진행축(flex-direction)이 바뀌는 순간 헷갈리기 시작함.

95 of 96

참고 문서

CSS Flexible Box Layout Module Level 1

https://www.w3.org/TR/css-flexbox-1/

TEST CSS FLEXBOX RULES

http://flexbox.help/

FLEXBOX FROGGY

http://flexboxfroggy.com/

CSS flexible 레아아웃: flex item의 팽창과 수축.

http://naradesign.net/wp/2017/04/20/2363/

CSS flexible 레아아웃: flex item의 방향과 순서.

http://naradesign.net/wp/2017/04/24/2440/

CSS flexible 레아아웃: flex item의 정렬과 간격.

http://naradesign.net/wp/2017/05/02/2467/

CSS flex: Webkit, Android 2.1~4.3, IE 10 문제 해결.

http://naradesign.net/wp/2017/05/19/2543/

https://github.com/philipwalton/flexbugs

96 of 96