728x90
Flex 가 등장한 이유
- mozila 재단에서 운영하는 문서에 따르면 Flexible Box, Flex Box 라고 불리는 Flex 는 1차원 레이아웃 배치를 위한 모델이라고 설명하고 있습니다.
여기서 말하는 1차원 레이아웃 이라는 말의 의미는 Grid 의 2차원 레이아웃과는 대조되는 개념입니다.
왜냐하면 Flex 는 row 혹은 column을 동시에 제어할 수 있는 Grid 와는 달리 주축을 중심으로한 제어의 기능을 수행하기 때문이라고 설명하고 있습니다.
아무튼 1차원 레이아웃 모델인 Flex 는 레이아웃 배치 전용 기능으로 개발되었는데, 그 이전에는 레이아웃을 만들 때 쓸 수 있는 기능이 마땅치 않았기 때문에 float 이나 inline-block 등을 이용한 방식을 보완하기 위한 목적이었습니다.
Flex 가 사용 되는 구조 이해하기
- 본격적으로 flex 에 대해서 공부하기 전에 flex 가 사용되는 기본적인 틀을 이해하고 넘아가겠습니다.
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
- 우선 flex 가 사용되는 HTML 구조는 위와 같습니다.
부모 container 가 있으며 직계 자식들이 flex item 이 됩니다. - flex 에서 사용되는 속성은 크게 2가지로 나뉘게 됩니다.
하나는 container 에 적용되는 속성들이고 하나는 item 들에 적용되는 속성들입니다.
크게 2가지 속성들이 flex 에 있다는 것을 알아두고 다음을 읽어가시면 될 것 같습니다.
Flex 의 두 개의 축 (main axis & cross axis)
- Flex 를 사용하기 위해서는 main axis 와 cross axis 라는 두 개의 축을 이해하고 있어야 합니다.
- main axis 는 flex-direction 속성을 활용하여 row & row-reverse 혹은 column & column-reverse 으로 설정할 수 있습니다.


- 여기서 주의 깊게 봐야 하는 점은 flex-direction 을 row 혹은 row-reverse 로 설정하면 main axis 가 row 를 기준이 된다는 것을 의미하기 때문에 자연스럽게 cross axis 는 column 을 기준으로 동작하게 됩니다.
반대로 flex-direction 이 column 혹은 column-reverse 라면 main axis 가 row 라는 것을 의미하기 때문에 cross axis 는 row 를 기준으로 동작하게 됩니다.
Flex-direction 에 따라 달라지는 writing mode
- 영어 사용권자들은 글을 쓸 때 왼쪽 위에서 시작해서 오른쪽 아래에서 끝나게 됩니다.
하지만 Flex 는 다양한 글쓰기 방식을 지원하기 위해 flex-direction에 따라 시작 지점과 끝 지점이 달라지게 됩니다.
위에서 본 것처럼 row reverse 를 하면 오른쪽이 1번 순차적으로 왼쪽으로 갈수록 내용이 이어지게 되며 콘텐츠도 오른쪽에 딱 붙어서 출력되는 것을 확인할 수 있습니다.
마찬가지로 column 과 column reverse 에서도 writing mode 는 달리지게 됩니다.
Flex Container & Flex Item & default setting
- Flex box laid out(레이아웃)이 사용되는 지역을 Flex Container라고 부릅니다.
- Flex Container 를 생성하기 위해서는 container 의 display 속성을 flex 혹은 inline-flex 로 설정하면 됩니다.
- Flex Container 의 display 속성이 설정되면 container 의 직계 자식들은 그 즉시 flex item 으로 설정됩니다.
- 다른 모든 CSS 요소들이 그러하듯, flex item 으로 설정된 요소들에게도 그 즉시 적용되는 default 속성들이 있는데요. 다음과 같은 것들이 자동으로 설정되게 됩니다.
- flex-direction 속성의 default 값은 row 입니다.
- Flex item 들은 flex direction row 에 따라서 나열되게 됩니다. (inline 요소들처럼 붙어서 표현됨)
- Flex item 들은 main axis 의 start edge 부터 순서대로 쌓이게 됩니다.
- Flex item 들은 main axis 방향으로 자동으로 stretch 하지 않습니다. (무슨 말이냐면 flex direction 이 row 일 때 container 의 width 가 300 px 이라면 해당 300 px 을 다 채우기 위해서 item 들의 컨텐츠 너비보다 더 크게 확장하지는 않는다는 말이다)
- Flex item 들은 main axis 방향으로 자동으로 shrink 합니다.
- Flex item 들은 cross axis 방향으로 자동으로 stretch 합니다.
(무슨 말이냐면 flex direction 이 row 일 때, container 의 height 가 300 px 이라면 item 의 콘텐츠 height 가 300px 보다 작더라도 자동으로 늘어나서 채우게 된다는 말이다)
- flex-basis 속성의 default 값은 auto 이다.
- flex-wrap 속성의 default 값은 nowrap 이다. - 이런 기본 속성들이 의미하는 바는 다음과 같습니다.
- flex item 들은 자동으로 row 에 차곡 차곡 쌓인다.
- flex item 의 content 사이즈만큼만 main axis 를 차지합니다.
- 만약 flex item 의 컨텐츠의 사이즈가 container 의 main axis 크기보다 크다면 wrap (밑 행으로 떨어져서 표기되는 것) 하지 않고 overflow (화면 오른쪽 바깥으로 나가서 보이지 않는 영역이 생긴다) 하게 됩니다.
- 만약 flex item 들 중에 cross axis 방면으로 크기가 더 큰 item 이 있다면 해당 item 의 cross axis 크기에 맞추어서 다른 item 들도 크기를 자동으로 stretch 합니다.
Changing flex-direction
- flex container 에게 flex-direction 속성과 해당하는 속성 값을 부여하는 방식으로 우리는 flex item 들이 어떻게 display(배치)될지 결정할 수 있습니다
예를 들어서 flex-direction 을 row-reverse 로 설정하면 start line 과 end line 이 바뀌게 되고 화면에 출력되는 모습도 완전히 달라지게 됩니다.
Multi-line flex containers with flex-wrap
- 우리가 지금까지 쓰고 보았던 flex 속성은 single line flex container 에 대한 내용들이었습니다.
우리가 원한다면 flex item 들을 여러 줄에 걸쳐서 wrap(자동 줄바꿈?) 되도록 할 수 있습니다.
다만, 이렇게 할 경우 각 line 들은 각각 새로운 flex container 가 생성되어 flex item 을 갖게 된다는 것을 꼭 알아두어야 합니다. - wrapping 이 실행되도록 하기 위해서는 flex-wrap 속성을 wrap 속성 값으로 설정하면 됩니다.
이렇게 하면 flex item 들이 한 줄(main axis)에 표현될 수 있는 것보다 커지게 될 때 다른 줄로 wrap 하게 됩니다.

- 위 그림에서 item 들은 container 의 main axis 가 포함할 수 있는 크기보다 더 큰 크기를 갖고 있습니다. 따라서 우리가 flex-wrap 속성 값을 wrap 으로 설정하면 위와 같이 wrap 이 진행되는 것을 알 수 있습니다.
이 그림에서 다시 한번 이야기하지만, 각 line 은 독자적인 container 가 있다는 것을 알아두어야 합니다. 이 말인 즉슨 첫 line 에서 다 채우지 못한 공백은 다음 line 에서 채워넣거나 하는 등의 영향은 발생하지 않는다는 것입니다.
flex-nowrap 으로 설정하면(flex-wrap 의 default 값입니다), 초과 되는 부분은 부모 main axis 크기 너비에 맞추기 위해 shrink 하게 됩니다.
한편 nowrap 을 사용하는 경우에 만약 item 들이 shrink 되는 것이 금지되도록 설정되었거나 shrink 하더라도 부모 main axis 의 크기를 초과할 경우 overflow 가 발생할 수 있습니다.
Flex flow Shorthand
- Flex flow 속성을 활용하면 flex-direction 과 flex-wrap 을 한 번에 표기할 수 있습니다.
두 속성 값을 입력하는데, 두 값은 띄어쓰기로 구분하며 첫 번째 값은 flex-direction 을 의미하며 두 번째 값은 flex-wrap 값을 의미합니다.
#parent2 {
flex-flow: row wrap;
}
- 위와 같이 표현할 수 있습니다.
Properties applied to flex items (available space)
- 이번에는 flex item 에 적용되는 속성들에 대해서 알아봅시다.
크게 3가지 속성이 있습니다.
flex-grow
flex-shrink
flex-basis
입니다. - flex item 에 적용되는 3가지 속성들을 자세히 알아보기 전에 먼저 이해해야 하는 개념이 있습니다.
바로 available space(가용 가능 공간) 입니다.

- container 의 가용 가능한 전체 크기가 500 px 인데, item 들이 300 px 을 차지하고 있다면 available space 는 200px 입니다.
이 available space 를 item 들이 어떻게 사용하게 하는지를 컨트롤 하는 것이 item property 3가지 입니다.
이제 하나씩 차례대로 알아보겠습니다.
The flex-basis property
- flex-basis 속성은 해당 속성을 부여받은 item 이 main axis 에 대해서 기본적으로 가지게 될 최소 크기를 의미합니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
}
div {
margin-top: 20px;
}
p {
border: solid 1px;
width: 300px;
height: 100px;
}
.child1 {
background-color: lavender;
flex-basis: auto;
}
.child2 {
background-color: darkgray;
flex-basis: content;
}
.child3 {
background-color: gold;
flex-basis: 200px;
}
.parent {
display: flex;
}
#parent1 {
flex-direction: column;
}
#parent2 {
flex-flow: row wrap;
}
#paren3 {
flex-wrap: wrap;
}
#parent4 {
border: 3px solid red;
justify-content: center;
flex-basis: auto;
}
</style>
</head>
<body>
<h1>flex로 자식요소들 정렬하기</h1>
<div class="parent" id="parent1">
<p class="child1">child1</p>
<p class="child2">child2</p>
<p class="child3">child3</p>
</div>
<div class="parent" id="parent2">
<p class="child1">child1</p>
<p class="child2">child2</p>
<p class="child3">child3</p>
</div>
<div class="parent" id="parent3">
<p class="child1">child1</p>
<p class="child2">child2</p>
<p class="child3">child3</p>
<p class="child1">child1</p>
<p class="child2">child2</p>
<p class="child3">child3</p>
</div>
<div class="parent" id="parent4">
<p class="child1">child1</p>
<p class="child2">child2</p>
<p class="child3">child3</p>
</div>
</body>
</html>

- 위 예시를 보면 flex-direction 이 column 으로 되어 있는 parent1 의 경우 main axis 가 column 이기 때문에 세로 크기가 flex-basis 로 부여받은대로 표현된 것을 확인할 수 있습니다.
반면에 flex-direction 이 row 로 되어 있는 parent2 의 경우 main axis 가 row 이기 때문에 가로 크기가 flex-basis 에서 부여받은대로 표현된 것을 확인할 수 있습니다.
The flex-grow property
- flex-grow 속성은 flex item 들이 main axis 의 available space 를 차지할 수 있는 권한을 부여합니다.
무슨 말이냐면

- 위 그림으로 예를 들어 보겠습니다.
만약 우리가 a item 에게 flex-grow: 1; 을 주게 된다면 a item 은 남은 available space 차지할 권한을 갖게 됩니다. 따라서 a item 은 300 px 을 차지하고 b, c 는 원래 차지하던 100 px 을 차제하게 됩니다.
만약 우리가 a, b item 에게 flex-grow: 1; 을 주게 된다면 a, b item 은 남은 available space 를 균등하게 나누어 갖을 권한을 갖게 됩니다. a, b item 은 200 px 을 차지하게 되고 c는 원래 차지하던 100 px 을 차지하게 됩니다.
그런데, 재미있는 점이 하나 있습니다. main axis 의 available space 를 차지할 비율을 우리가 임의로 지정해줄 수 있다는 점인데요.
a item 에게 flex-grow : 2 를 주고 b item 에게 flex-grow : 1 을 주게 되면 a 와 b item 은 2 : 1 비율로 available space 를 차지하게 됩니다.

- 위 그림은 child1 에게 flex-grow : 1 의 속성을 부여한 결과값입니다. main axis 의 available space를 child1 이 차지한 것을 알 수 있습니다.
The flex-shrink property
- flex-shrink 속성은 item 들의 크기가 container 의 main axis 의 크기보다 커졌을 때 크기를 줄여줄 권한을 부여합니다.
여기서 shrink 한다는 것은 flex-basis 가 정한 크기보다 줄어들 수 있다는 것을 의미합니다.
flex-grow 처럼 값을 임의로 부여할 수 있는데, flex-grow 와 같이 shrink 하는 비율을 우리가 임의로 지정할 수 있다는 것을 의미합니다.
flex-shrink 속성 값을 크게 부여받으면 더 다른 item 보다 더 빠른 속도로 shrink 하게 됩니다.
Shorthand values for the flex properties (flex shorthand)
- 앞서 container 의 속성들 빠르게 입력할 수 있었던 flex-flow 와 마찬가지로 item 들의 속성을 빠르게 입력할 수 있는 방법이 flex 입니다.
flex 속기법은 3가지 값을 갖습니다.
flex-grow
flex-shrink
flex-basis
이렇게 3가지입니다.

- 예를 들어 위와 같이 flex: 1 1 auto; 로 설정하면 flex-grow 1 , flex-shrink 1, flex-basis auto 로 설정하는 것과 같은 효과를 갖습니다.
- 한편, 이 flex shorthand 에는 predefined 된 속성값들이 있습니다.
flex: initial;
initial 값은 flex item 들의 속성값을 초기 값으로 설정합니다. 즉 flex: 0 1 auto 로 설정한다는 의미입니다.
flex: none;
none 값은 nonflexible 한 item 으로 만듭니다. 즉 flex: 0 0 auto 로 설정한다는 의미입니다.
flex: auto;
auto 값은 모든 flex 를 설정한다는 의미입니다. 즉 flex: 1 1 auto 로 설정한다는 의미입니다.
Alignment, justification and distribution of free space between items
- Flexbox 의 가장 강력한 기능 중 하나는 바로 main axis 와 cross axis 를 기준으로하여 item 들을 align 하거나 justify 할 수 있다는 것입니다. 명심해야 하는 점은 flex item 들에 적용되는 속성들이므로 반드시 container 직계 부모를 가진 flex item 들에만 적용하여야 정상적으로 작동합니다.
align-items
- align-items 속성은 item 들을 cross axis 를 기준으로 정렬 시킵니다.
defualt 값은 stretch 입니다. (이 때문에 container 를 flex 로 설정하는 순간 cross axis 가 가장 큰 item 을 기준으로 다른 item 들도 같이 stretch 합니다)
align-items 속성 값으로 사용되는 것들은 4가지가 있습니다.
- stretch(default)
- flex-start
- flex-end
- center

- 유념해서 보아야 하는 것은 flex-start 와 flex-end, flex-center 로 설정을 하면 stretch 를 하지 않는다는 점입니다.
justify-content
- justify-content 속성은 main axis 를 기준으로 item 들을 정렬합니다.
default 값은 flex-start 로 container 를 flex 로 설정하면 start line 에서 딱 붙어서 요소들이 붙는 이유입니다.
justify-content 속성 값에는 align-items 에는 없는 속성 값들이 있습니다.
space-between 속성 값은 start line 과 end line 에 요소 하나씩을 배치시킨 이후에 남은 공간들을 균등하게 배분하는 방식입니다.

- 위와 같이 표현됩니다.
space-evenly 는 start line 과 end line 에 요소를 배치하지 않고 요소들 사이 그리고 start & end 사이에 균등한 space 를 갖도록 합니다.

- 위와 같이 표현됩니다.
space-around 는 space evenly 와 비슷하지만 다른 점이 있는데, 각 요소 좌 우에 동일한 space 를 갖게 됩니다.

- 우와 같이 표현됩니다. (start line 과 one 요소간의 거리가 one 요소와 two 요소 간의 거리의 1/2 입니다)
Flex 포스팅을 읽느라 고생 많으셨습니다.
ㅎㅎ 성공적으로 포스팅을 작성한 나 자신에게도 축하와 격려의 박수를 보냅니다.
고생 많으셨고, Flex 를 충분히 이해하게 되었기를 바랍니다.
참고
: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox
: https://studiomeal.com/archives/197