이 게시물은 2020년 10월 25일 수정판입니다.
Flexbox Layout은, 새롭게 CSS3 명세에 반영된 레이아웃 모듈로서, 요소들이 수용된 공간을 어떻게 효과적으로 채워나갈지에 대한 아이디어에서 시작된 새로운 레이아웃 방식입니다.
이 명세는 IE 버전 11 이하에서 제조사 전용속성을 필요로 하지만, 앞으로의 레이아웃 방식을 완전히 대체할 만한 기술이므로 반드시 학습하길 권합니다.
Flexbox로 레이아웃을 잡으면 모바일을 포함한 하이브리드 앱으로 만들때도 별도의 추가작업이 필요하지 않습니다.
Flexbox는, 유연한 요소(내용물), 그리고 그 요소를 담을 그릇으로 이루어집니다. 다시말해, 부모 태그에 사용할 클래스와 자식 태그에 사용할 클래스, 두 가지로 나뉘어 있습니다.
그릇에 해당하는 부모 요소(이하, 컨테이너라 칭함)에 display: flex
혹은 display: inline-flex
로 flexbox임을 선언할 수 있습니다.
.container { display: flex }
1
2
3
4
5
컨테이너 안에 위치하는 자식 요소(이하 아이템이라 칭함)에 어떤 방향성을 줄 것인지 결정합니다.
.container { display: flex; flex-direction: row; }
위 이미지처럼, flexbox는 내용물을 상하좌우 여러방향에 걸쳐 정렬할 수 있기 때문에, 차세대 레이아웃 방식으로 각광받고 있습니다.
예제 이미지를 너무 정확히 이해하려고 하지 않아도 됩니다. 앞으로 속성 설명을 하다보면 자연히 익히게 됩니다.
1
2
3
4
5
아이템의 줄 넘김을 처리합니다.
.container { display: flex; flex-direction: row; flex-wrap: nowrap; }
flex-direction과 flex-wrap 속성을 단축해서 사용할 수 있는 Shorcut 속성이 있습니다. flex-flow 속성을 사용하면 flex-flow: row wrap
처럼 첫 값에는 flex-direction, 두 번째 값에 flex-wrap을 선언할 수 있습니다.
1
2
3
4
5
컨테이너에 빈 공간이 있을 경우, 아이템을 수평방향(Main Axis)으로 정렬하는 방식을 선언합니다.
.container { display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: flex-start; }
1
2
3
4
5
컨테이너에 빈 공간이 있을 경우, 아이템을 수직방향(Cross Axis)으로 정렬하는 방식을 선언합니다. justify-content
의 수직 버전이라고 생각해도 좋습니다.
.container { display: flex; flex-flow: row nowrap; align-items:flex-start; }
정렬 값 중에서, baseline 정렬이 개념 상 난해하다면 아래 예제를 참고하세요. 여기에서는 숫자가 컨테이너의 baseline 형태를 암시적으로 보여주고 있습니다. 각 아이템들이 컨테이너의 baseline을 중심으로 정렬합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
컨테이너에 빈 공간이 있을 경우, 한 줄을 넘기는 아이템들을 수직방향(Cross Axis)으로 정렬하는 방식입니다. align-item
과 justify-content
속성이 가지는 특징들을 모두 포함하고 있습니다.
이 속성은 많은 아이템이 한 줄 이상 넘어가는 경우에 사용합니다. 만일 아이템이 한 줄을 넘지 않으면 이 속성은 효과를 내지 않습니다.
.container { display: flex; flex-flow: row nowrap; align-content:flex-start; }
이제부터는 컨테이너 안에 위치할 아이템이 가지는 속성에 대해 설명합니다. 컨테이너 속성과 아이템 속성은 반드시 구분해서 사용해야 합니다. 아래에 설명하는 속성은 반드시 부모 요소 컨테이너에 display: flex
가 선언되어 있어야 합니다.
1
2
3
4
5
컨테이너 안에서 아이템이 나열되는 순서를 선언합니다. 숫자가 작을수록 시작이며, 높을수록 끝에 위치합니다. 포지셔닝 : Position에서 설명한 z-index
속성과 같은 방식이며, 음수 사용이 가능합니다.
.item-01 { order: -1 } .item-02 { order: 1 } .item-03 { order: 2 } .item-04 { order: 3 } .item-05 { order: 99 }
order
속성이 선언되면, HTML이나 CSS에서 구문을 어떤 순서에 따라 작성했는지와 상관없이, 오직 order
에 선언된 값에 의해서만 순서가 정해집니다. 무슨 뜻인지 잘 이해가 안간다면 여기를 클릭해서 예제를 참고하세요. 예문에서는 HTML과 CSS 구문의 순서를 섞어 놓은 상태입니다.
1
2
3
4
5
.item { flex-grow: 0 }
아이템이 컨테이너에서 차지할 부피를 확장합니다. 기본 값은 0이며, 숫자가 높을 수록 다른 아이템의 곱절 단위로 부피가 늘어납니다. 예를들어 grow 값이 2인 아이템은, grow가 1인 아이템 2개를 합한 크기가 됩니다. 이 경우, 전체 아이템의 부피는 다시 계산되어 화면에 랜더링 됩니다.
값이 0인 상태는 너비 값이 없으며, 다른 아이템들의 값이 모두 0이고 자기 혼자만 1 혹은 그 이상인 경우, 나머지 모든 공간을 차지합니다.
여러 아이템을 한 줄에 자동으로 꽉 채우고 싶다면, 굳이 width="25%"
와 같은 속성을 정의해서 갯수에 제한을 둘 필요 없이, flex-grow 속성을 사용해서 간단히 구현할 수 있습니다. 위 예제에서 모든 요소에 각각 1씩 올려보십시오.
.container { display: flex } .container .items { flex-grow: 1 }
flex-grow
와 flex-shrink
속성은 음수를 사용하지 않습니다.
1
2
3
4
5
.item { flex-shrink: 1 }
flex-grow의 반대 속성으로 보이지만, 계산 방식은 다릅니다. 기본 값은 1이며, 숫자가 높을수록 상대적으로 다른 아이템보다 부피를 축소합니다.
이 속성에 대해서는 영문을 포함한 많은 문서를 읽고 있지만, 부모와 자식 요소에 정의 된 다른 속성에 간섭을 많이 받기에, 저 역시 알기쉽고 명확하게 설명 할 만큼 정리가 되지 않은 상태입니다. 이 속성을 해석하기 위한 좋은 문건을 알고 계신 분은 코멘트 해 주세요.
.item { flex-basis: 100px }
아이템의 기본 크기 값을 선언합니다. 단위로는 길이(px, em, rem..)과 %(퍼센테이지) 모두 사용할 수 있습니다. 이 속성은 다른 아이템의 속성과도 맞물려 매우 많은 경우의 수를 제공하기도 합니다. 여러 응용 방법에 대해서는 관련 문서를 찾는데로 추가하겠습니다.
이 링크를 통해 이 속성의 간략한 사용법을 파악할 수 있습니다. 바로 아래 flex 속성 예제에서도 테스트 해보세요.
1
2
.item { flex: 1 }
flex-grow, flex-shrink 그리고 flex-basis 속성을 한번에 기재하는 단축선언입니다. 기본 값은 0 1 auto
이며, flex-shrink와 flex-basis는 옵션 값으로서, 기재하지 않으면 자동적으로 기본 값이 선언됩니다.
위 예문에서의 flex: 1
은 flex-grow: 1
과 같은 의미가 됩니다.
1
2
3
4
5
.item { align-self: stretch }
부모 요소인 컨테이너에서 선언한 정렬방식 안에서, 특정 아이템이 독자적인 정렬 값을 선언할 수 있습니다. 선언할 수 있는 값은 이전에 컨테이너 부분에서 설명한 align-items와 동일합니다.
코드하이라이터가 호환성 문제로 제대로 표시되지 않고 있습니다. 보시기 불편해도 양해 바랍니다.
우와.. 이미지 좌우반전 검색하다가 들어오게 됐는데 엄청 좋은 걸 얻어가네요. 좋은 게시물 감사합니다~
감사합니다 혹시 블로그에 글을 쓰기 위해서 참고를 하려고 하는데 사진을 가져가도 될까요?
저도 이미지를 가져온 것들이 있는데 전부 출처를 적어 놓았으니 가져가실 때 같이 적어 놓으시면 되겠죠?^^
안녕하세요. horizontal layout 홈페이지를 만드는데 큰 도움이 되었습니다.
한가지 질문이 있는데요.
크롬, 파폭에서는 정상적으로 나오는데
IE에서 자식요소들의 width 값이 무시된채 줄어들어서 나오는데 무엇이 문제일까요?
flex-basis로 명시해줘도 적용이 안되네요.
IE에서의 호환성 문제는 너무 많은 경우의 수가 있어서 제가 재현을 하기엔 무리죠 ㅎㅎ
-ms-display:flexbox; 로 해결했습니다.
정말 정말 잘 봤습니다.
position: fixed로 sticky header나 footer를 만들거나
float 속성으로 컬럼을 나누고, 또 clear 해줘야하는 번거로움이 사라졌네요.
얼른 IE9도 죽고 IE10부터 맞춰도 되는 세상이 오면 좋겠네요.
IE9 점유율 아직도 높으려나요 ㅠㅠ
IE9 점유율은 신경 안쓰셔도 될 것 같아요^^
align-items 속성 설명 부분에
flex-end를 flex-enter로 오타
baseline 속성은 없는 것으로 아는데 집어넣으셨네요~
flexbox 안쓰고 세로 가운데정렬하실때 어떻게하시나 궁금하네요
그나저나 처음알았는데 좋은것같습니다~~~감사합니다
flexbox를 안쓰는 조건 하에서도 여러가지 경우에 따라 방법이 따로 있습니다. 예를들어 객체의 높이 값이 지정되어 있으냐 아니면 유동적이냐에 따라서 방법이 달라지는 따위 입니다. 거의 모든 경우에 대한 방법을 설명한 글이 있으니 참고하세요.
https://css-tricks.com/centering-css-complete-guide/
감사합니다 ㅎㅎ