🎉 berenickt 블로그에 온 걸 환영합니다. 🎉
Lang
CSS
07-Flexbox 레이아웃

1. 실습 - 워밍업

본격적으로 Flexible Box Layout을 공부하기 전에 워밍업 차원에서 실습 문제를 하나 풀어보겠습니다. 기본으로 제공되는 실습 코드를 실행하면 아래와 같이 보입니다.

CSS_7_1

이를 아래와 같이 보일 수 있도록 CSS 스타일을 적용해주세요.

CSS_7_2


1.1 HTML

1
<!doctype html>
2
<html lang="ko">
3
<head>
4
<meta charset="UTF-8" />
5
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
<title>[실습] 워밍업</title>
8
<link href="style.css" rel="stylesheet" />
9
</head>
10
<body>
11
<!-- 기본 제공 HTML 코드 -->
12
<div class="flex-container">
13
<div class="flex-item red-box">A</div>
14
<div class="flex-item blue-box">B</div>
15
<div class="flex-item green-box">C</div>
16
</div>
17
</body>
18
</html>

1.2 CSS

1
/* 기본 제공 CSS 코드 */
2
.flex-container {
3
width: 300px;
4
height: 300px;
5
border: 4px solid black;
6
}
7
.flex-item {
8
width: 50px;
9
height: 50px;
10
color: white;
11
font-size: 20px;
12
}
13
.red-box {
14
background-color: red;
15
}
16
.blue-box {
17
background-color: blue;
18
}
19
.green-box {
20
background-color: green;
21
}

문제를 푸는 방법은 크게 두 가지가 있습니다.

  1. float 속성을 사용해서 정렬하는 방법
    • 텍스트는 text-align 속성을 사용해서 center 값으로 지정하면 수평 방향에서 중앙으로 정렬할 수 있습니다.
    • 그리고 수직 방향에서 중앙 정렬은 line-height 속성의 값을 HTML 요소의 높이 값과 똑같이 지정하면 됩니다.
    • (1.3)의 방법
  2. display 속성의 값으로 inline-block으로 지정하는 방법

1.3 CSS 정답 - float

1
.flex-container {
2
width: 300px;
3
height: 300px;
4
border: 4px solid black;
5
}
6
.flex-item {
7
width: 50px;
8
height: 50px;
9
color: white;
10
font-size: 20px;
11
/* ⭐ 정렬을 위한 속성 추가 */
12
float: left;
13
text-align: center;
14
line-height: 50px;
15
}
16
.red-box {
17
background-color: red;
18
}
19
.blue-box {
20
background-color: blue;
21
}
22
.green-box {
23
background-color: green;
24
}

2. Flexible Box Layout이란?

MDN Flexbox : https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox

Flexible Box Layout은 흔히 Flexible Layout라고도 불리며 1차원 방식으로 효과적으로 레이아웃을 설계할 수 있도록 고안된 레이아웃 스타일입니다. 여기서 1차원이란 수평(가로, row)이나 수직(세로, column) 방향 중 한 방향으로만 레이아웃을 설계하는 방식을 말합니다.

Flexible Box Layout에는 이런 1차원 방식으로 HTML 요소를 디자인하는 속성들이 많이 추가되어서 과거보다 훨씬 간단하게 1차원 레이아웃을 구성할 수 있게 되었습니다. 워밍업으로 풀었던 CSS를 다시 보겠습니다.


2.1 CSS 정답 - Flexbox

1
.flex-container {
2
width: 300px;
3
height: 300px;
4
border: 4px solid black;
5
background-color: #fff;
6
/* 자식관계에 있는 요소만 flex되기 떄문에 자식의 자식에서 또 flex 적용 가능 */
7
display: flex; /* parent의 자식요소인 .box를 수평 정렬 */
8
}
9
.flex-item {
10
width: 50px;
11
height: 50px;
12
color: white;
13
font-size: 20px;
14
/* .box의 자식요소인 text를 정렬 */
15
display: flex;
16
justify-content: center;
17
align-items: center;
18
}
19
.red-box {
20
background-color: red;
21
}
22
.blue-box {
23
background-color: blue;
24
}
25
.green-box {
26
background-color: green;
27
}

3. Flex Container

3.1 display

display 속성으로 Flex Container를 정의합니다.

의미기본값
flexBlock 특성의 Flex Container를 정의
inline-flexInline 특성의 Flex Container를 정의

flexinline-flex는 차이는 단순합니다. display: flex;로 지정된 Flex Container는 Block 요소와 같은 성향(수직 쌓임)을 가지며, display: inline-flex로 지정된 Flex Container는 Inline(Inline Block) 요소와 같은 성향(수평 쌓임)을 가집니다.

여기서 말하는 수직과 수평 쌓임은 Items가 아니라 Container라는 것에 주의합시다. 두 값의 차이는 내부에 Items에는 영향을 주지 않습니다.

CSS_7_3

1
.flex-container {
2
width: 300px;
3
height: 300px;
4
border: 4px solid black;
5
background-color: #fff;
6
/* 플렉스 박스 레이아웃이 되고, 관련 속성을 사용할 수 있게 만듬 */
7
/* 정렬을 적용하려는 요소의 부모 요소에 flex를 지정 */
8
display: flex;
9
}
10
.flex-item {
11
width: 50px;
12
height: 50px;
13
color: white;
14
font-size: 20px;
15
}
16
.red-box {
17
background-color: red;
18
}
19
.blue-box {
20
background-color: blue;
21
}
22
.green-box {
23
background-color: green;
24
}

3.2 메인 축과 교차 축

이렇게 수평정렬이 되는 이유를 알려면, Flexible Box Layout의 기본 개념이 필요합니다.

CSS_7_4

  • flex container
    • 메인축(main axis)과 교차축(cross axis) 개념이 생김
    • 메인축의 기본값은 왼쪽에서 오른쪽으로
    • 교차축의 기본값은 위에서 아래로
  • flex item
    • flex container의 자식 관계에 있는 아이템
    • 메인축의 방향으로 배치됨
    • 메인축의 방향이 바뀌게 되면, flex item의 배치도 변경됨 (flex-direction)
  • 시작점(flex-start)끝점(flex-end)

3.2.1 flex-direction: 메인 축 방향 결정

container에 적용하는 속성으로 container안의 item의 메인축 방향을 설정합니다.

의미기본값
rowItmes를 수평축(왼쪽에서 오른쪽으로)으로 표시row
row-reverseItems를 row의 반대 축으로 표시
columnItems를 수직축(위에서 아래로)으로 표시
column-reverseItems를 column의 반대 축으로 표시

플렉스 박스 레이아웃은 기본으로 flex-direction 속성값이 row로 적용됩니다. flex-direction 속성값에 따라 주축 방향과 플렉스 아이템 배치가 다음 그림처럼 달라집니다.

CSS_7_5

1
.flex-container {
2
width: 300px;
3
height: 300px;
4
border: 4px solid black;
5
background-color: #fff;
6
/* 플렉스 박스 레이아웃이 되고, 관련 속성을 사용할 수 있게 만듬 */
7
/* 정렬을 적용하려는 요소의 부모 요소에 flex를 지정 */
8
display: flex;
9
/* 📝 flex-direction : 플렉스 컨테이너의 주축을 변경할 떄 사용 */
10
flex-direction: row;
11
}
12
.flex-item {
13
width: 50px;
14
height: 50px;
15
color: white;
16
font-size: 20px;
17
}
18
.red-box {
19
background-color: red;
20
}
21
.blue-box {
22
background-color: blue;
23
}
24
.green-box {
25
background-color: green;
26
}

3.2.2 justify-content: 메인 축 정렬

주 축(main-axis)의 정렬 방법을 설정합니다.

의미
flex-startItems를 시작점(flex-start)으로 정렬 (기본값)
flex-endItems를 끝점(flex-end)으로 정렬
centerItems를 가운데 정렬
space-between시작 Item은 시작점에, 마지막 Item은 끝점에 정렬되고 나머지 Items는 사이에 고르게 정렬됨
space-aroundItems를 균등한 여백을 포함하여 정렬
space-evenly플렉스 아이템 사이와 양끝의 간격이 균일하도록 정렬합니다.

CSS_7_6

1
.flex-container {
2
width: 300px;
3
height: 300px;
4
border: 4px solid black;
5
background-color: #fff;
6
display: flex;
7
flex-direction: row;
8
/* 📝 justify-content : 주축의 방향에서 좌, 우, 중앙 정렬을 할 떄 사용 */
9
justify-content: center;
10
}
11
.flex-item {
12
width: 50px;
13
height: 50px;
14
color: white;
15
font-size: 20px;
16
}
17
.red-box {
18
background-color: red;
19
}
20
.blue-box {
21
background-color: blue;
22
}
23
.green-box {
24
background-color: green;
25
}

3.2.3 flex-wrap: 줄바꿈

Items의 여러 줄 묶음(줄 바꿈)을 설정합니다.

의미기본값
nowrap모든 Itmes를 여러 줄로 묶지 않음(한 줄에 표시)nowrap
wrapItems를 여러 줄로 묶음
wrap-reverseItems를 wrap의 역 방향으로 여러 줄로 묶음

CSS_7_7

플렉스 박스 레이아웃은 플렉스 아이템의 개수를 늘려 플렉스 컨테이너를 초과하게 해도 플렉스 아이템이 절대로 줄 바꿈되지 않습니다.

1
.flex-container {
2
width: 300px;
3
height: 300px;
4
border: 4px solid black;
5
background-color: #fff;
6
display: flex;
7
flex-wrap: wrap;
8
}
9
.flex-item {
10
width: 101px;
11
height: 50px;
12
color: white;
13
font-size: 20px;
14
}
15
.red-box {
16
background-color: red;
17
}
18
.blue-box {
19
background-color: blue;
20
}
21
.green-box {
22
background-color: green;
23
}

3.3 align-content: 교차축 정렬 (2줄 이상)

교차 축(cross-axis)의 정렬 방법을 설정합니다. 주의할 점은 flex-wrap 속성을 통해 Items가 여러 줄(2줄 이상)이고 여백이 있을 경우만 사용할 수 있습니다.

Items가 한 줄일 경우 align-items 속성을 사용하세요.

의미
stretchContainer의 교차 축을 채우기 위해 Items를 늘림 (기본값)
flex-startItems를 시작점(flex-start)으로 정렬
flex-endItems를 끝점(flex-end)으로 정렬
centerItems를 가운데 정렬
space-between시작 Item은 시작점에, 마지막 Item은 끝점에 정렬되고 나머지 Items는 사이에 고르게 정렬됨
space-aroundItems를 균등한 여백을 포함하여 정렬

CSS_7_8

1
.flex-container {
2
width: 300px;
3
height: 300px;
4
border: 4px solid black;
5
background-color: #fff;
6
display: flex;
7
/* 📝 align-content : 2줄 이상일 떄, 교차축 정렬 */
8
align-content: center;
9
flex-wrap: wrap;
10
}
11
.flex-item {
12
width: 101px;
13
height: 50px;
14
color: white;
15
font-size: 20px;
16
}
17
.red-box {
18
background-color: red;
19
}
20
.blue-box {
21
background-color: blue;
22
}
23
.green-box {
24
background-color: green;
25
}

3.4 align-items: 교차축 정렬 (1줄)

교차 축(cross-axis)에서 Items의 정렬 방법을 설정합니다. Items가 한 줄일 경우 많이 사용합니다.

주의할 점은 Items가 flex-wrap을 통해 여러 줄(2줄 이상)일 경우에는 align-content 속성이 우선합니다. 따라서 align-items를 사용하려면 align-content 속성을 기본값(stretch)으로 설정해야 합니다.

의미
stretchContainer의 교차 축을 채우기 위해 Items를 늘림 (기본값)
flex-startItems를 각 줄의 시작점(flex-start)으로 정렬
flex-endItems를 각 줄의 끝점(flex-end)으로 정렬
centerItems를 가운데 정렬
baselineItems를 문자 기준선에 정렬

CSS_7_9

1
.flex-container {
2
width: 300px;
3
height: 300px;
4
border: 4px solid black;
5
background-color: #fff;
6
display: flex;
7
flex-direction: row;
8
justify-content: center;
9
/* 📝 align-items : 교차축 방향에서 플렉스 아이템을 정렬할 떄 사용 */
10
/* stretch : 교차축 방향을 꽉차게 늘리라는 의미, height가 지정되어 있으면 무시됨 */
11
align-items: center;
12
}
13
.flex-item {
14
width: 50px;
15
height: 50px; /* stretch 속성값을 위해 height 지워보기 */
16
color: white;
17
font-size: 20px;
18
}
19
.red-box {
20
background-color: red;
21
}
22
.blue-box {
23
background-color: blue;
24
}
25
.green-box {
26
background-color: green;
27
}

3.5 flex-flow: 단축 속성

container에 적용하는 속성으로 flex-direction 속성과 flex-wrap 속성을 한 번에 사용할 수 있는 단축 속성입니다. 다음처럼 작성된 flex 속성이 있다고 해 봅시다.

1
.flex-container {
2
width: 300px;
3
height: 300px;
4
border: 4px solid black;
5
background-color: #fff;
6
display: flex;
7
/* flex-direction: column; */
8
/* flex-wrap: nowrap; */
9
/* flex-direction 속성과 flex-wrap 속성을 한 번에 사용할 수 있는 단축 속성 */
10
flex-flow: column nowrap;
11
}
12
.flex-item {
13
width: 101px;
14
height: 50px;
15
color: white;
16
font-size: 20px;
17
}
18
.red-box {
19
background-color: red;
20
}
21
.blue-box {
22
background-color: blue;
23
}
24
.green-box {
25
background-color: green;
26
}

4. Flex Items

HTML을 다음과 같이 수정하겠습니다.

1
<!doctype html>
2
<html lang="ko">
3
<head>
4
<meta charset="UTF-8" />
5
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
<title>flexbox</title>
8
<link href="style.css" rel="stylesheet" />
9
</head>
10
<body>
11
<div class="flex-container">
12
<div class="flex-item red-box">A</div>
13
<div class="flex-item blue-box">BBBBB</div>
14
<div class="flex-item green-box">C</div>
15
</div>
16
</body>
17
</html>

4.1 order: Item의 순서를 설정

Item의 순서를 설정합니다. Item에 숫자를 지정하고 숫자가 클수록 순서가 밀립니다. 음수가 허용됩니다.

HTML 구조와 상관없이 순서를 변경할 수 있기 때문에 유용합니다.

의미기본값
숫자Item의 순서를 설정0

CSS_7_10


4.2 flex 단축 속성

Item의 너비(증가, 감소, 기본)를 설정하는 단축 속성입니다.

의미기본값
flex-growItem의 증가 너비 비율을 설정0
flex-shrinkItem의 감소 너비 비율을 설정1
flex-basisItem의 (공간 배분 전) 기본 너비 설정auto
1
/* flex: 증가너비 감소너비 기본너비; */
2
flex: 1 1 20px; /* 증가너비 감소너비 기본너비 */
3
flex: 1 1; /* 증가너비 감소너비 */
4
flex: 1 20px; /* 증가너비 기본너비 (단위를 사용하면 flex-basis가 적용됩니다) */

4.2.1 flex-basis: 기본 너비 설정

Item이 감소하는 너비의 비율을 설정합니다. 숫자가 크면 더 많은 너비가 감소합니다. Item이 가변 너비가 아니거나, 값이 0이면 효과가 없습니다.

의미기본값
숫자Item의 감소 너비 비율을 설정1

CSS_7_11

1
* {
2
box-sizing: border-box;
3
}
4
.flex-container {
5
width: 100%;
6
height: 300px;
7
border: 4px solid black;
8
background-color: #fff;
9
display: flex;
10
}
11
.flex-item {
12
color: white;
13
font-size: 20px;
14
/* 📝 flex-basis : flex-item의 기본 크기를 50으로 지정 */
15
/* flex-item의 너비는 자동으로 content 너비만큼 적용됨 */
16
/* 50px이 되지 않는 플렉스 아이템들은 50px로, 50px이 넘는 플렉스 아이템은 콘텐츠 너비만큼 적용 */
17
flex-basis: 50px;
18
}
19
.red-box {
20
background-color: red;
21
}
22
.blue-box {
23
background-color: blue;
24
}
25
.green-box {
26
background-color: green;
27
}

4.2.2 flex-grow: 증가 너비 비율 설정

Item의 증가 너비 비율을 설정합니다. 숫자가 크면 더 많은 너비를 가집니다. Item이 가변 너비가 아니거나, 값이 0일 경우 효과가 없습니다.

의미기본값
숫자Item의 증가 너비 비율을 설정0

모든 Items의 총 증가 너비(flex-grow)에서 각 Item의 증가 너비의 비율 만큼 너비를 가질 수 있습니다. 예를 들어, Item이 3개이고 증가 너비가 각각 1, 2, 1이라면,

  • 첫 번째 Item은 총 너비의 25%(1/4)을,
  • 두 번째 Item은 총 너비의 50%(2/4)를,
  • 세 번째 Item은 총 너비의 25%(1/4)을 가지게 됩니다.

CSS_7_12

1
* {
2
box-sizing: border-box;
3
}
4
.flex-container {
5
width: 100%;
6
height: 300px;
7
border: 4px solid black;
8
background-color: #fff;
9
display: flex;
10
}
11
.flex-item {
12
color: white;
13
font-size: 20px;
14
flex-basis: 50px;
15
}
16
/* 📝 flex-grow : flex-basis의 크기 값을 제외하고 나머지 여백을 일정한 비율로 나눠가지는 속성 */
17
/* 속성값으로는 비율에 해당하는 값을 적용 */
18
/* 자식 요소에 1:2:1 비율로 적용함 */
19
.red-box {
20
background-color: red;
21
flex-grow: 1;
22
}
23
.blue-box {
24
background-color: blue;
25
flex-grow: 2;
26
}
27
.green-box {
28
background-color: green;
29
flex-grow: 1;
30
}

4.2.3 flex-shrink: 감소 너비 비율을 설정

Item이 감소하는 너비의 비율을 설정합니다. 숫자가 크면 더 많은 너비가 감소합니다. Item이 가변 너비가 아니거나, 값이 0이면 효과가 없습니다.

의미기본값
숫자Item의 감소 너비 비율을 설정1

CSS_7_13

1
* {
2
box-sizing: border-box;
3
}
4
.flex-container {
5
width: 100%;
6
height: 300px;
7
border: 4px solid black;
8
background-color: #fff;
9
display: flex;
10
}
11
.flex-item {
12
color: white;
13
font-size: 20px;
14
flex-basis: 50px;
15
/* 📝 flex-shrink : flex-item이 flex-basis 속성으로 설정된 크기보다 더 작아질 수 있는지 결정 */
16
/* 속성값은 0 또는 1(기본값)을 사용 */
17
/* 0은 작아질 수 없다, 1은 작아질 수 있다 */
18
/* 브라우저의 너비가 줄어들어, flex-basis의 값이 보장되지 않을 떄 자동으로 줄어듬 */
19
/* 이는 flex-shrink의 기본값이 1이기 때문 */
20
/* 0으로 지정하면, 브라우저의 넓이가 flex-basis의 값이 보장되지 않을 때, 최소 크기를 보장받습니다. */
21
/* 단, flexbox의 전체적인 영역은 브라우저 영역을 빠져나가면서 적용됨 */
22
flex-shrink: 0;
23
}
24
.red-box {
25
background-color: red;
26
}
27
.blue-box {
28
background-color: blue;
29
}
30
.green-box {
31
background-color: green;
32
}

4.3 align-self : 교차축에서 개별 item 정렬

교차 축(cross-axis)에서 개별 Item의 정렬 방법을 설정합니다. align-items는 Container 내 모든 Items의 정렬 방법을 설정합니다. 필요에 의해 일부 Item만 정렬 방법을 변경하려고 할 경우 align-self를 사용할 수 있습니다. 이 속성은 align-items 속성보다 우선합니다.

의미
autoContainer의 align-items 속성을 상속받음 (기본값)
stretchContainer의 교차 축을 채우기 위해 Item을 늘림
flex-startItem을 각 줄의 시작점(flex-start)으로 정렬
flex-endItem을 각 줄의 끝점(flex-end)으로 정렬
centerItem을 가운데 정렬
baselineItem을 문자 기준선에 정렬

CSS_7_14


4.4 word-break: 콘텐츠 짤리면 줄넘김

1
* {
2
box-sizing: border-box;
3
}
4
.flex-container {
5
width: 100%;
6
height: 300px;
7
border: 4px solid black;
8
background-color: #fff;
9
display: flex;
10
}
11
.flex-item {
12
color: white;
13
font-size: 20px;
14
flex-basis: 50px;
15
/* 📝 모든 플렉스 아이템에 강제로 동일한 너비를 갖게하고 싶다면 */
16
width: 40px;
17
/* 이때, 콘텐츠가 짤리는 경우에 발생하는데, 이를 해결하려면 아래 코드 적용 */
18
word-break: break-all;
19
}
20
.red-box {
21
background-color: red;
22
}
23
.blue-box {
24
background-color: blue;
25
}
26
.green-box {
27
background-color: green;
28
}

5. 출처


6. Flex 게임 : Flexbox Froggy

https://flexboxfroggy.com/#ko


Level 1 ~ 4 : justify-content

1
parent {
2
justify-content: flex-start; /* flex-end, center, space-between, space-around, space-evenly */
3
}

기본 축으로 정렬한다.

기본값은 flex-start로 자식 요소의 시작 방향으로 정렬한다.

  • flex-end은 종료 방향, center는 가운데 방향,
  • space-between은 좌우 사이 간격을 균일하게, space-around는 주위 간격을 균일하게,
  • space-evenly는 균일하게 배치하면서 양 끝의 간격에도 여백을 적용한다.

Level 5 ~ 7 : align-items

1
parent {
2
align-items: flex-start; /* flex-end, center, space-between, space-around, space-evenly */
3
}

반대 축으로 정렬한다. 값은 justy-content와 동일하다.


Level 8 ~ 13 : flex-direction

1
parent {
2
flex-direction: row; /* row-reverse, column, column-reverse */
3
}

자식 요소의 기본축 정렬 방향을 변경한다. 기본값은 row로 기본축을 가로로 지정한다.

  • column은 세로,
  • row-reversecolumn-reverse는 각각 가로, 세로 역순으로 정렬한다.

Level 14, 15 : order

1
child {
2
order: 숫자;
3
}

자식 요소의 순서를 지정한다.


Level 16, 17 : align-self

1
child {
2
align-self: flex-start; /* flex-end, center, space-between, space-around, space-evenly */
3
}

선택한 자식 요소만 정렬을 바꿀 수 있다.


Level 18, 19 : flex-wrap

1
parent {
2
flex-wrap: nowrap; /* wrap */
3
}

자식 요소에 줄 바꿈을 할지 적용한다. 기본값은 nowrap으로 줄 바꿈을 하지 않는다. 값을 wrap으로 하면 자식 요소들이 줄 바꿈을 한다.


Level 20 : flex-flow

1
parent {
2
flex-flow: flex-direction flex-wrap;
3
}

flex-directionflex-wrap을 한꺼번에 적용한다.


Level 21 ~ 24 : align-content

1
parent {
2
align-content: flex-start; /* flex-end, center, space-between, space-around, space-evenly */
3
}

align-items와 같은 축으로 정렬한다.

차이점은 align-items은 줄 바꿈이 없을 때 사용하고, align-content는 줄 바꿈이 있을 때 사용한다.


추가 : flex-grow와 flex-shrink

1
child {
2
flex-grow: 숫자;
3
flex-shrink: 숫자;
4
}
  • flex-grow는 기본값은 0으로,
    • 해당 숫자를 늘리면, 크기를 늘렸을 때 남은 공간만큼 다른 자식 요소들의 크기 대비 더 많이 늘어난다.
  • flex-shrink는 기본값은 1로,
  • 해당 숫자를 늘리면 크기를 줄였을 때 다른 자식 요소들의 크기 대비 더 많이 줄어든다.