...
CSS Flexbox
Flexbox는 모던 웹을 위하여 제안된 기존 layout보다 더 세련된 방식의 니즈에 부합하기 위한 CSS3의 새로운 layout 방식이다. 요소의 사이즈가 불명확하거나 동적으로 변화할 때에도 유연한 레이아웃을 실현할 수 있다. 복잡한 레이아웃이라도 적은 코드로 보다 간단하게 표현할 수 있다.
Q. 요즘 다들 grid 쓰는데, flex이제 안쓰는거 아닙니까?
A. 정답은 No다.
물론 grid로만 레이아웃을 모두 구현은 가능하다. 하지만 단순한 컨텐츠를 가로 정렬하는데는 flex가 훨씬 간단하게 구현이 가능 하기 때문에, grid는 2차원 행렬 같이 큰 틀 레이아웃을 구현 할때 쓰고, flex는 1차원 행렬 같이 안의 컨텐츠 아이템을 가로 정렬할때 자주 쓴다고 보면 된다.
다음은 실전 예제이고, 큰 틀(파랑)은 grid로 짜고 네모 안의 사진이나 글자 컨텐츠들은 flex(빨강)으로 사용한걸 확인 할 수 있다.
Flexbox 기본 구조
Flexbox 레이아웃은 flex item이라 불리는 복수의 자식 요소와 이들을 내포하는 flex-container 부모 요소로 구성된다.
flexbox를 사용하기 위해서 HTML 부모 요소의 display 속성에 flex를 지정한다. (부모 요소가 inline 요소인 경우 inline-flex을 지정한다.)
값 | 의미 |
flex | Block 특성의 Flex Container를 정의 |
inline-flex | Inline 특성의 Flex Container를 정의 |
.flex-container {
display: flex;
}
.flex-container-inline {
display: inline-flex;
}
Container 와 item
flexbox에서 사용하는 속성은 부모 요소인 flex container에 정의하는 속성과 자식 요소인 flex item에 정의하는 속성으로 나누어진다.
전체적인 정렬이나 흐름에 관련된 속성은 flex container에 정의하고, 자식 요소의 크기나 순서에 관련된 속성은 flex item에 정의한다고 보면 된다.
Flex Container 속성
속성 | 의미 |
display | Flex Container를 정의 |
flex-flow | flex-direction와 flex-wrap의 단축 속성 |
flex-direction | Flex Items의 주 축(main-axis)을 설정 |
flex-wrap | Flex Items의 여러 줄 묶음(줄 바꿈) 설정 |
justify-content | 주 축(main-axis)의 정렬 방법을 설정 |
align-content | 교차 축(cross-axis)의 정렬 방법을 설정(2줄 이상) |
align-items | 교차 축(cross-axis)에서 Items의 정렬 방법을 설정(1줄) |
flex-direction
- flex-direction 속성은 flex 컨테이너의 주축(main axis) 방향을 설정한다.
flex-direction: row;
좌에서 우로(ltr) 수평 배치된다. flex-direction 속성의 기본값이다.
flex-direction: row-reverse;
우에서 좌로(rtl) 수평 배치된다.
flex-direction: column;
위에서 아래로 수직 배치된다.
flex-direction: column-reverse;
아래에서 위로 수직 배치된다.
유의할점은, Items 순서를 거꾸로 뒤집거나, 수직으로 설정 할 경우, 주 축과 교차축 모두 변하게 된다. 즉, 방향(수평, 수직)에 따라 주 축과 교차 축이 달라진다.
flex-wrap
- flex-wrap 속성은 flex 컨테이너의 복수 flex item을 1행으로 또는 복수행으로 배치한다.
- flex는 기본적으로 1차원 형태이다.
- flex 컨테이너의 width보다 flex item들의 width의 합계가 더 큰 경우, 한줄로 표현할 것인지, 여러줄로 표현할 것인지를 지정한다.
flex-wrap: nowrap;
flex item을 개행하지 않고 1행에 배치한다. flex-wrap 속성의 기본값이다.
각 flex item의 폭은 flex container에 들어갈 수 있는 크기로 축소된다.
flex-wrap: wrap;
flex item들의 width의 합계가 flex 컨테이너의 width보다 큰 경우, flex item을 복수행에 배치한다.
기본적으로 좌에서 우로, 위에서 아래로 배치된다.
flex-wrap: wrap-reverse;
flex-wrap: wrap;과 동일하나 아래에서 위로 배치된다.
flex-flow
- flex-flow 속성은 flex-direction 속성과 flex-wrap 속성을 설정하기 위한 shorthand이다.
- 기본값은 row nowrap이다.
/* flex-flow: <flex-direction> || <flex-wrap>; */
/* flex-flow: 주축 여러줄묶음; */
flex-flow: row-reverse wrap;
justify-content
- flex container의 main axis를 기준으로 flex item을 수평 정렬한다.
justify-content: flex-start;
main start(좌측)를 기준으로 정렬한다. justify-content 속성의 기본값이다.
justify-content: flex-end;
main end(우측)를 기준으로 정렬한다.
flex-direction: row-reverse;과 다른 점은, 1,2,3,4,5 순서는 그대로 인점
justify-content: center;
flex container의 중앙에 정렬한다.
justify-content: space-between;
첫번째와 마지막 flex item은 좌우 측면에 정렬되고 나머지와 균등한 간격으로 정렬된다.
justify-content: space-around;
모든 flex item은 균등한 간격으로 정렬된다.
align-content
- flex container의 cross axis를 기준으로 flex item을 수직 정렬한다. (두 줄 이상일 경우)
[align-conent / justiry-content]
- align-conent : 아이템을 수직 정렬
- justiry-content : 아이템을 수평 정렬
[align-content / align-items ]
- align-content : 아이템이 두줄 이상일때 수직 정렬
- align-items : 아이템이 한줄일때 수직 정렬
align-content: stretch;
모든 flex item은 flex item의 행 이후에 균등하게 분배된 공간에 정렬되어 배치된다. align-content 속성의 기본값이다.
align-content: flex-start;
모든 flex item은 flex container의 cross start 기준으로 stack 정렬된다.
align-content: flex-end;
모든 flex item은 flex container의 cross end 기준으로 stack 정렬된다.
align-content: center;
모든 flex item은 flex container의 cross axis의 중앙에 stack 정렬된다.
align-content: space-between;
첫번째 flex item의 행은 flex container의 상단에 마지막 flex item의 행은 flex container의 하단에 배치되며 나머지 행은 균등 분할된 공간에 배치 정렬된다.
align-content: space-around;
모든 flex item은 균등 분할된 공간 내에 배치 정렬된다.
align-items
- flex item을 flex container의 수직 방향(cross axis)으로 정렬한다. (한 줄일 경우)
- align-items 속성은 모든 flex item에 적용된다.
align-items: stretch;
모든 flex item은 flex container의 높이(cross start에서 cross end까지의 높이)에 꽉찬 높이를 갖는다. align-items 속성의 기본값이다.
align-items: flex-start;
모든 flex item은 flex container의 cross start 기준으로 정렬된다.
align-items: flex-end;
모든 flex item은 flex container의 cross end 기준으로 정렬된다.
align-items: center;
모든 flex item은 flex container의 cross axis의 중앙에 정렬된다.
align-items: baseline;
모든 flex item은 flex container의 baseline을 기준으로 정렬된다.
즉, flex item 박스 크기가 제각각 이라해도, 안의 텍스트를 기준으로 맞춘다.
Flex Item 속성
float, clear, vertical-align 속성은 flex item에 영향을 주지 않는다.
속성 | 의미 |
order | Flex Item의 순서를 설정 |
flex | flex-grow, flex-shrink, flex-basis의 단축 속성 |
flex-grow | Flex Item의 증가 너비 비율을 설정 |
flex-shrink | Flex Item의 감소 너비 비율을 설정 |
flex-basis | Flex Item의 (공간 배분 전) 기본 너비 설정 |
align-self | 교차 축(cross-axis)에서 Item의 정렬 방법을 설정 |
order
- flex item의 배치 순서를 지정한다.
- HTML 코드를 변경하지 않고 order 속성값을 지정하는 것으로 간단히 재배치할 수 있다.
- 기본 배치 순서는 flex container에 추가된 순서이다. 기본값은 0이다.
.flex-item {
order: 정수값;
}
flex-grow
- flex item의 너비에 대한 확대 인자(flex grow factor)를 지정한다.
- 기본값은 0이고 음수값은 무효하다.
- 모든 flex item이 동일한 flex-grow 속성값을 가지면 모든 flex item은 동일한 너비를 갖는다.
.flex-item {
flex-grow: 양의 정수값;
}
예를 들어 Item이 3개이고 총너비가 400px, 증가 너비가 각각 1, 2, 1이라면,
- 첫 번째 Item은 총 너비의 25%(1/4)을,
- 두 번째 Item은 총 너비의 50%(2/4)를,
- 세 번째 Item은 총 너비의 25%(1/4)을 가지게 된다.
.flex-item-1 {
flex-grow: 1;
}
.flex-item-2{
flex-grow: 2;
}
.flex-item-3 {
flex-grow: 1;
}
예제 코드)
See the Pen flex-grow by park young woong (@heropark) on CodePen.
flex-shrink
- flex item의 너비에 대한 축소 인자(flex shrink factor)를 지정한다. 기본값은 1이고 음수값은 무효하다.
- 0을 지정하면 축소가 해제되어 원래의 너비를 유지한다.
.flex-item {
flex-shrink: 양의 정수값;
}
기본적으로 모든 flex item은 축소된 상태로 지정(기본값 1)하고 두번째 flex item만 축소를 해제(flex-shrink: 0;)하면 원래의 너비를 유지한다.
계산이 까다롭기 때문에 활용도는 조금 떨어진다고 생각한다. 원리 정도만 이해하고 넘어갑시다.
flex-basis
- flex item의 너비 기본값을 px, % 등의 단위로 지정한다. 기본값은 auto이다.
.flex-item {
flex-basis: auto; /* 가변 Item과 같은 너비 */
}
.flex-item-4 {
flex-basis: 350px;
}
flex
- flex-grow, flex-shrink, flex-basis 속성의 shorthand이다.
- 기본값은 0 1 auto이다.
/* flex: none | auto | [ <flex-grow> <flex-shrink>? || <flex-basis> ]; */
/* flex: 증가너비 감소너비 기본너비; */
flex: 1 1 20px; /* 증가너비 감소너비 기본너비 */
flex: 1 1; /* 증가너비 감소너비 */
flex: 1 20px; /* 증가너비 기본너비 (단위를 사용하면 flex-basis가 적용됩니다) */
flex-grow를 제외한 개별 속성은 생략할 수 있다.
만약 flex: 1;로 작성하면 flex-grow: 1;과 같다.
그러면 나머지 속성은 생략했으니 기본값이 적용되어 flex-shrink: 1;, flex-basis: auto;가 되겠죠?
즉 flex: 1; 혹은 flex: 1 1;은 flex: 1 1 auto;와 같다고 볼 수 있다만 그렇지 않는다.
flex-basis의 기본값은 auto입니다만 단축 속성인 flex에서 그 값을 생략할 경우 0이 적용된다.
다시 정리하면 flex: 1; 혹은 flex: 1 1;은 flex: 1 1 0;이 된다는 것이다.
이 부분을 기억하지 않으면 엉뚱한 결과가 나올 수 있으니 주의합시다!
align-self
- flex item을 수직 방향(cross axis)으로 정렬한다
- align-items 속성보다 우선하여 개별 flex item을 정렬한다. 기본값은 auto이다.
.flex-item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
3번째, 4번째 flex item은 align-self 속성값이 우선 적용되어 정렬된다.
See the Pen Flexbox playground by Gabi (@enxaneta) on CodePen.
# 참고자료
https://poiemaweb.com/css3-flexbox
https://webdir.tistory.com/349
https://d2.naver.com/helloworld/8540176
https://velog.io/@bearsjelly/css-flex
https://heropy.blog/2018/11/24/css-flexible-box/
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.