플렉스 레이아웃
다양한 디바이스에 따라 다양한 레이아웃의 유형을 배웁니다.
플렉스 레이아웃
flexbox는 뷰포트나 요소의 크기가 불명확하거나 동적으로 변할 때에도 효율적으로 요소를 배치, 정렬, 분산할 수 있는 방법을 제공하는 CSS3의 새로운 레이아웃 방식입니다. flexbox의 장점을 한 마디로 표현하면 '복잡한 계산 없이 요소의 크기와 순서를 유연하게 배치할 수 있다'라고 할 수 있다. 정렬, 방향, 순서, 크기 등을 유연하게 조절할 수 있기 때문에 별도의 분기 처리를 줄일 수 있고, CSS만으로 다양한 레이아웃을 구현할 수 있습니다.
flexbox는 복수의 자식 요소인 flex item과 그 상위 부모 요소인 flex container로 구성됩니다.
부모 요소와 자식 요소에 정의하는 속성 구분
flexbox에서 사용하는 속성은 부모 요소인 flex container에 정의하는 속성과 자식 요소인 flex item에 정의하는 속성으로 나누어집니다.. 전체적인 정렬이나 흐름에 관련된 속성은 flex container에 정의하고, 자식 요소의 크기나 순서에 관련된 속성은 flex item에 정의합니다. 이를 분리해 적용하는 것이 중요합니다.
- flex container 속성: flex-direction, flex-wrap, justify-content, align-items, align-content
- flex item 속성: flex, flex-grow, flex-shrink, flex-basis, order
flexbox 지원 범위
flexbox는 Internet Explorer 10 이상이 지원합니다. 하지만 Internet Explorer 10 이상이 완전히 지원하지는 않아 Internet Explorer 10과 Internet Explorer 11에서 버그가 발견되기도 합니다. 그래서 PC용 서비스에 flexbox를 적용하기에는 아직 이른 감이 있으며, 만약 Internet Explorer를 지원하지 않는 서비스를 운영한다면 flexbox를 적용해 봐도 좋습니다.
flex 관련 속성
속성 | 설명 |
---|---|
align-content | align-content 속성은 콘텐츠의 상하관계 정렬 상태를 정의합니다. |
align-items | align-items 속성은 콘텐츠 내부의 정렬 상태를 정의합니다. |
align-self | align-self 속성은 콘텐츠의 정렬 상태를 정의합니다. |
flex | flex 속성은 콘텐츠의 성질을 flex로 정의합니다. |
flex-basis | flex-basis 속성은 요소의 기본 단위를 정의합니다. |
flex-direction | flex-direction 속성은 요소의 정렬 방향을 정의합니다. |
flex-flow | flex-flow 속성은 요소의 정렬 방향과 줄 속성을 설정합니다. |
flex-grow | flex-grow 속성은 요소의 크기를 숫자를 통해 정의합니다. |
flex-shrink | flex-shrink 속성은 요소의 크기를 숫자를 통해 줄여줍니다. |
flex-wrap | flex-wrap 속성은 요소의 줄 속성을 설정합니다. |
justify-content | justify-content 속성은 콘텐츠의 좌우 관계 정렬 상태를 정의합니다. |
order | order 속성은 flex 콘텐츠의 순서를 정의합니다. |
Sample1
콘텐츠 요소의 상하 관계 정렬 상태를 설정하는 예제입니다.
결과
TOTAL
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex</title>
<style>
/* option */
.flex {
background-color: #f7f7f7;
border-radius: 3px;
padding: 20px;
counter-reset: items;
}
.item {
border-radius: 3px;
background-color: #A2CBFA;
border: 1px solid #4390E1;
box-sizing: border-box;
box-shadow: 0 2px 2px rgba(0,90,250,0.05), 0 4px 4px rgba(0,90,250,0.05), 0 8px 8px rgba(0,90,250,0.05), 0 16px 16px rgba(0,90,250,0.05);
min-height: 100px;
color: #fff;
padding: 10px;
}
.item::before {
counter-increment: items;
content: counter(items);
}
/* flex */
.flex1 {display: flex;}
.item1 {flex-grow: 1;}
.item1 + .item1 {margin-left: 2%;}
</style>
</head>
<body>
<div class="flex flex1">
<div class="item item1"></div>
<div class="item item1"></div>
<div class="item item1"></div>
<div class="item item1"></div>
<div class="item item1"></div>
<div class="item item1"></div>
<div class="item item1"></div>
<div class="item item1"></div>
</div>
</body>
</html>
Sample2
콘텐츠 요소의 상하 관계 정렬 상태를 설정하는 예제입니다.
결과
TOTAL
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex</title>
<style>
/* option */
.flex {
background-color: #f7f7f7;
border-radius: 3px;
padding: 20px;
counter-reset: items;
}
.item {
border-radius: 3px;
background-color: #A2CBFA;
border: 1px solid #4390E1;
box-sizing: border-box;
box-shadow: 0 2px 2px rgba(0,90,250,0.05), 0 4px 4px rgba(0,90,250,0.05), 0 8px 8px rgba(0,90,250,0.05), 0 16px 16px rgba(0,90,250,0.05);
min-height: 100px;
color: #fff;
padding: 10px;
}
.item::before {
counter-increment: items;
content: counter(items);
}
/* flex */
.flex2 {display: flex;}
.item2 {flex-grow: 1;}
.item2:nth-child(4) {flex-grow: 2;}
.item2 + .item2 {margin-left: 2%;}
</style>
</head>
<body>
<div class="flex flex2">
<div class="item item2"></div>
<div class="item item2"></div>
<div class="item item2"></div>
<div class="item item2"></div>
<div class="item item2"></div>
<div class="item item2"></div>
<div class="item item2"></div>
<div class="item item2"></div>
</div>
</body>
</html>
Sample3
콘텐츠 요소의 상하 관계 정렬 상태를 설정하는 예제입니다.
결과
TOTAL
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex</title>
<style>
/* option */
.flex {
background-color: #f7f7f7;
border-radius: 3px;
padding: 20px;
counter-reset: items;
}
.item {
border-radius: 3px;
background-color: #A2CBFA;
border: 1px solid #4390E1;
box-sizing: border-box;
box-shadow: 0 2px 2px rgba(0,90,250,0.05), 0 4px 4px rgba(0,90,250,0.05), 0 8px 8px rgba(0,90,250,0.05), 0 16px 16px rgba(0,90,250,0.05);
min-height: 100px;
color: #fff;
padding: 10px;
}
.item::before {
counter-increment: items;
content: counter(items);
}
/* flex */
.flex3 {display: flex; flex-direction: row-reverse;}
.item3 {width: 100px; margin-left: 2%;}
</style>
</head>
<body>
<div class="flex flex3">
<div class="item item3"></div>
<div class="item item3"></div>
<div class="item item3"></div>
<div class="item item3"></div>
</div>
</body>
</html>
Sample4
콘텐츠 요소의 상하 관계 정렬 상태를 설정하는 예제입니다.
결과
TOTAL
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex</title>
<style>
/* option */
.flex {
background-color: #f7f7f7;
border-radius: 3px;
padding: 20px;
counter-reset: items;
}
.item {
border-radius: 3px;
background-color: #A2CBFA;
border: 1px solid #4390E1;
box-sizing: border-box;
box-shadow: 0 2px 2px rgba(0,90,250,0.05), 0 4px 4px rgba(0,90,250,0.05), 0 8px 8px rgba(0,90,250,0.05), 0 16px 16px rgba(0,90,250,0.05);
min-height: 100px;
color: #fff;
padding: 10px;
}
.item::before {
counter-increment: items;
content: counter(items);
}
/* flex */
.flex4 {display: flex;}
.item4 {width: 100px;}
.item4 + .item4 {margin-left: 2%;}
.item4:last-child {margin-left: auto;}
</style>
</head>
<body>
<div class="flex flex4">
<div class="item item4"></div>
<div class="item item4"></div>
<div class="item item4"></div>
<div class="item item4"></div>
</div>
</body>
</html>
Sample5
콘텐츠 요소의 상하 관계 정렬 상태를 설정하는 예제입니다.
결과
TOTAL
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex</title>
<style>
/* option */
.flex {
background-color: #f7f7f7;
border-radius: 3px;
padding: 20px;
counter-reset: items;
}
.item {
border-radius: 3px;
background-color: #A2CBFA;
border: 1px solid #4390E1;
box-sizing: border-box;
box-shadow: 0 2px 2px rgba(0,90,250,0.05), 0 4px 4px rgba(0,90,250,0.05), 0 8px 8px rgba(0,90,250,0.05), 0 16px 16px rgba(0,90,250,0.05);
min-height: 100px;
color: #fff;
padding: 10px;
}
.item::before {
counter-increment: items;
content: counter(items);
}
/* flex */
.flex5 {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.item5 {
width: 49%;
height: 100px;
margin-bottom: 2%;
}
.item5:nth-child(3n) {
width: 100%;
}
</style>
</head>
<body>
<div class="flex flex5">
<div class="item item5"></div>
<div class="item item5"></div>
<div class="item item5"></div>
<div class="item item5"></div>
<div class="item item5"></div>
</div>
</body>
</html>
Sample6
콘텐츠 요소의 상하 관계 정렬 상태를 설정하는 예제입니다.
결과
TOTAL
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex</title>
<style>
/* option */
.flex {
background-color: #f7f7f7;
border-radius: 3px;
padding: 20px;
counter-reset: items;
}
.item {
border-radius: 3px;
background-color: #A2CBFA;
border: 1px solid #4390E1;
box-sizing: border-box;
box-shadow: 0 2px 2px rgba(0,90,250,0.05), 0 4px 4px rgba(0,90,250,0.05), 0 8px 8px rgba(0,90,250,0.05), 0 16px 16px rgba(0,90,250,0.05);
min-height: 100px;
color: #fff;
padding: 10px;
}
.item::before {
counter-increment: items;
content: counter(items);
}
/* flex */
.flex6 {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.item6 {
/* flex: 0 32%; flex-grow / flex-basis */
flex-basis: 32%;
height: 100px;
margin-bottom: 2%;
}
</style>
</head>
<body>
<div class="flex flex6">
<div class="item item6"></div>
<div class="item item6"></div>
<div class="item item6"></div>
<div class="item item6"></div>
<div class="item item6"></div>
<div class="item item6"></div>
<div class="item item6"></div>
<div class="item item6"></div>
<div class="item item6"></div>
</div>
</body>
</html>
Sample7
콘텐츠 요소의 상하 관계 정렬 상태를 설정하는 예제입니다.
결과
TOTAL
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex</title>
<style>
/* option */
.flex {
background-color: #f7f7f7;
border-radius: 3px;
padding: 20px;
counter-reset: items;
}
.item {
border-radius: 3px;
background-color: #A2CBFA;
border: 1px solid #4390E1;
box-sizing: border-box;
box-shadow: 0 2px 2px rgba(0,90,250,0.05), 0 4px 4px rgba(0,90,250,0.05), 0 8px 8px rgba(0,90,250,0.05), 0 16px 16px rgba(0,90,250,0.05);
min-height: 100px;
color: #fff;
padding: 10px;
}
.item::before {
counter-increment: items;
content: counter(items);
}
/* flex */
.flex7 {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.item7 {
flex-basis: 32%;
padding-bottom: 30%;
margin-bottom: 2%;
}
</style>
</head>
<body>
<div class="flex flex7">
<div class="item item7"></div>
<div class="item item7"></div>
<div class="item item7"></div>
<div class="item item7"></div>
<div class="item item7"></div>
<div class="item item7"></div>
<div class="item item7"></div>
<div class="item item7"></div>
<div class="item item7"></div>
</div>
</body>
</html>
Sample8
콘텐츠 요소의 상하 관계 정렬 상태를 설정하는 예제입니다.
결과
TOTAL
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex</title>
<style>
/* option */
.flex {
background-color: #f7f7f7;
border-radius: 3px;
padding: 20px;
counter-reset: items;
}
.item {
border-radius: 3px;
background-color: #A2CBFA;
border: 1px solid #4390E1;
box-sizing: border-box;
box-shadow: 0 2px 2px rgba(0,90,250,0.05), 0 4px 4px rgba(0,90,250,0.05), 0 8px 8px rgba(0,90,250,0.05), 0 16px 16px rgba(0,90,250,0.05);
color: #fff;
padding: 10px;
}
.item::before {
counter-increment: items;
content: counter(items);
}
/* flex */
.flex8 {
display: flex;
justify-content: space-between;
/* align-items: flex-start;
align-items: center; */
align-items: flex-end;
height: 300px;
}
.item8 {
flex-basis: 10%;
margin-bottom: 2%;
}
.item8:nth-child(1) { height: 20%; }
.item8:nth-child(2) { height: 40%; }
.item8:nth-child(3) { height: 50%; }
.item8:nth-child(4) { height: 80%; }
.item8:nth-child(5) { height: 40%; }
.item8:nth-child(6) { height: 30%; }
.item8:nth-child(7) { height: 20%; }
</style>
</head>
<body>
<div class="flex flex8">
<div class="item item8"></div>
<div class="item item8"></div>
<div class="item item8"></div>
<div class="item item8"></div>
<div class="item item8"></div>
<div class="item item8"></div>
<div class="item item8"></div>
</div>
</body>
</html>
Sample9
콘텐츠 요소의 상하 관계 정렬 상태를 설정하는 예제입니다.
결과
TOTAL
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex</title>
<style>
/* option */
.flex {
background-color: #f7f7f7;
border-radius: 3px;
padding: 20px;
counter-reset: items;
}
.item {
border-radius: 3px;
background-color: #A2CBFA;
border: 1px solid #4390E1;
box-sizing: border-box;
box-shadow: 0 2px 2px rgba(0,90,250,0.05), 0 4px 4px rgba(0,90,250,0.05), 0 8px 8px rgba(0,90,250,0.05), 0 16px 16px rgba(0,90,250,0.05);
color: #fff;
padding: 10px;
}
.item::before {
counter-increment: items;
content: counter(items);
}
/* flex */
.flex9 {
display: flex;
justify-content: space-between;
flex-direction: column;
}
.item9 {
margin-bottom: 1%;
height: 14%;
}
.item9:nth-child(1) { width: 20%; }
.item9:nth-child(2) { width: 40%; }
.item9:nth-child(3) { width: 50%; }
.item9:nth-child(4) { width: 80%; }
.item9:nth-child(5) { width: 40%; }
.item9:nth-child(6) { width: 30%; }
.item9:nth-child(7) { width: 20%; }
</style>
</head>
<body>
<div class="flex flex9">
<div class="item item9"></div>
<div class="item item9"></div>
<div class="item item9"></div>
<div class="item item9"></div>
<div class="item item9"></div>
<div class="item item9"></div>
<div class="item item9"></div>
</div>
</body>
</html>
Sample10
콘텐츠 요소의 상하 관계 정렬 상태를 설정하는 예제입니다.
결과
TOTAL
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex</title>
<style>
/* option */
.flex {
background-color: #f7f7f7;
border-radius: 3px;
padding: 20px;
counter-reset: items;
}
.item {
border-radius: 3px;
background-color: #A2CBFA;
border: 1px solid #4390E1;
box-sizing: border-box;
box-shadow: 0 2px 2px rgba(0,90,250,0.05), 0 4px 4px rgba(0,90,250,0.05), 0 8px 8px rgba(0,90,250,0.05), 0 16px 16px rgba(0,90,250,0.05);
min-height: 100px;;
color: #fff;
padding: 10px;
}
.item::before {
counter-increment: items;
content: counter(items);
}
/* flex */
.flex10 {
display: flex;
flex-flow: column wrap;
align-content: space-between;
height: 700px;
}
.item10 {
width: 32%;
margin-bottom: 2%;
}
.flex10::before,
.flex10::after {
content: "";
flex-basis: 100%;
width: 0;
order: 2;
border: 1px solid #ddd;
}
.item10:nth-child(1) { height: 100px; }
.item10:nth-child(2) { height: 200px; }
.item10:nth-child(3) { height: 300px; }
.item10:nth-child(4) { height: 200px; }
.item10:nth-child(5) { height: 200px; }
.item10:nth-child(6) { height: 200px; }
.item10:nth-child(7) { height: 300px; }
.item10:nth-child(8) { height: 200px; }
.item10:nth-child(9) { height: 100px; }
.item10:nth-child(3n+1) { order: 1; }
.item10:nth-child(3n+2) { order: 2; }
.item10:nth-child(3n) { order: 3; }
</style>
</head>
<body>
<div class="flex flex10">
<div class="item item10"></div>
<div class="item item10"></div>
<div class="item item10"></div>
<div class="item item10"></div>
<div class="item item10"></div>
<div class="item item10"></div>
<div class="item item10"></div>
<div class="item item10"></div>
<div class="item item10"></div>
</div>
</body>
</html>
Sample11
콘텐츠 요소의 상하 관계 정렬 상태를 설정하는 예제입니다.
결과
TOTAL
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex</title>
<style>
/* option */
.flex {
background-color: #f7f7f7;
border-radius: 3px;
padding: 20px;
counter-reset: items;
}
.item {
border-radius: 3px;
background-color: #A2CBFA;
border: 1px solid #4390E1;
box-sizing: border-box;
box-shadow: 0 2px 2px rgba(0,90,250,0.05), 0 4px 4px rgba(0,90,250,0.05), 0 8px 8px rgba(0,90,250,0.05), 0 16px 16px rgba(0,90,250,0.05);
min-height: 100px;;
color: #fff;
padding: 10px;
}
.item::before {
counter-increment: items;
content: counter(items);
}
/* flex */
.flex11 {
display: flex;
flex-flow: column wrap;
align-content: space-between;
height: 780px;
}
.item11 {
width: 24%;
margin-bottom: 1%;
}
.item11:nth-of-type(1) { height: 100px; }
.item11:nth-of-type(2) { height: 200px; }
.item11:nth-of-type(3) { height: 300px; }
.item11:nth-of-type(4) { height: 200px; }
.item11:nth-of-type(5) { height: 200px; }
.item11:nth-of-type(6) { height: 200px; }
.item11:nth-of-type(7) { height: 200px; }
.item11:nth-of-type(8) { height: 100px; }
.item11:nth-of-type(9) { height: 100px; }
.item11:nth-of-type(10){ height: 100px; }
.item11:nth-of-type(11){ height: 100px; }
.item11:nth-of-type(12){ height: 300px; }
.item11:nth-of-type(13){ height: 300px; }
.item11:nth-of-type(14){ height: 200px; }
.item11:nth-of-type(4n+1) { order: 1; }
.item11:nth-of-type(4n+2) { order: 2; }
.item11:nth-of-type(4n+3) { order: 3; }
.item11:nth-of-type(4n) { order: 4; }
.item11.break {
flex-basis: 100%;
width: 0;
border: 1px solid #ddd;
margin: 0;
content: "";
padding: 0;
font-size: 0;
}
</style>
</head>
<body>
<div class="flex flex11">
<div class="item item11"></div>
<div class="item item11"></div>
<div class="item item11"></div>
<div class="item item11"></div>
<div class="item item11"></div>
<div class="item item11"></div>
<div class="item item11"></div>
<div class="item item11"></div>
<div class="item item11"></div>
<div class="item item11"></div>
<div class="item item11"></div>
<div class="item item11"></div>
<div class="item item11"></div>
<div class="item item11"></div>
<div class="item item11"></div>
<div class="item item11"></div>
<span class="item item11 break"></span>
<span class="item item11 break"></span>
<span class="item item11 break"></span>
</div>
</body>
</html>
Sample12
콘텐츠 요소의 상하 관계 정렬 상태를 설정하는 예제입니다.
결과
TOTAL
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex</title>
<style>
/* option */
.flex {
background-color: #f7f7f7;
border-radius: 3px;
padding: 20px;
counter-reset: items;
}
.item {
border-radius: 3px;
background-color: #A2CBFA;
border: 1px solid #4390E1;
box-sizing: border-box;
box-shadow: 0 2px 2px rgba(0,90,250,0.05), 0 4px 4px rgba(0,90,250,0.05), 0 8px 8px rgba(0,90,250,0.05), 0 16px 16px rgba(0,90,250,0.05);
min-height: 100px;;
color: #fff;
padding: 10px;
}
.item::before {
counter-increment: items;
content: counter(items);
}
/* flex */
.flex12 {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}
.item12 {margin-bottom: 2%;}
.item12:nth-child(1) {
/* flex-grow / flex-shrink / flex-basis : auto */
flex: 1 100%;
}
.item12:nth-child(2) {
flex: 1 0 0;
}
.item12:nth-child(3) {
flex: 3 0 0;
margin-left: 2%;
}
.item12:nth-child(4) {
flex: 1 0 0;
margin-left: 2%;
}
.item12:nth-child(5) {
flex: 1 100%;
}
/* mediaquery */
@media (max-width: 600px){
.item12:nth-child(3) {flex: 1 0 100%; margin-left: 0;}
.item12:nth-child(4) {margin-left: 0;}
}
</style>
</head>
<body>
<div class="flex flex12">
<div class="item item12"></div>
<div class="item item12"></div>
<div class="item item12"></div>
<div class="item item12"></div>
<div class="item item12"></div>
</div>
</body>
</html>