flex는 grid만큼 다양한 기능을 가지고 있지는 않지만, 대부분의 레이아웃은 flexbox의 조합만으로도 충분히 구현이 가능합니다.
grid layout에 관해서는 아래 깔끔하게 잘 정리된 글을 링크로 남깁니다.
https://studiomeal.com/archives/533
Flex Layout
Flex Layout은 css의 Flexbox를 활용한 화면구현 모델입니다. 복잡한 레이아웃을 간단하게 구현하거나 콘텐츠를 자동으로 정렬하는데 초점이 맞춰져 있는 개발자 친화적인 특징을 가지고 있습니다.
좋은 레이아웃은 웹사이트의 내용을 명확하고 직관적으로 전달하여 사용자 경험을 향상하는 데에 크게 기여합니다. 따라서 레이아웃을 구조적으로 설계하는 것은 프론트엔드 개발에서 굉장히 중요한 요소입니다.
css에 있는 레이아웃을 구현하는 다양한 방식 중에서 오늘은 flex layout에 대해 살펴보겠습니다.
1. 등장
과거 웹 디자인은 테이블, 플로트(float), 포지션(position) 등의 기법에 의존했습니다. 그러나 웹사이트의 기능과 시각적인 요소들이 다양해지면서 기존의 기법으로는 확장성 있는 웹 디자인을 설계하기 힘들어졌고, 새로운 시스템에 대한 니즈가 생겨나게 됩니다. flex layout은 복잡한 레이아웃을 쉽고 규칙적인 코드로 구현할 수 있게 해 주고, 다양한 크기의 디바이스에도 유연하게 대처할 수 있게 해 주면서 이러한 니즈를 충족시켜 주었습니다. Flexbox의 적절한 조합으로 이전에 비해 더 적은 코드로, 더 복잡한 화면을 구현할 수 있게 됩니다.
2. 기본 개념
Flexbox는 컨테이너 안에 있는 아이템들의 레이아웃을 효율적으로 조정할 수 있는 기능들을 제공합니다. 여기에서 컨테이너는 부모요소, 아이템은 자식 요소들을 의미합니다.
Flexbox는 주로 1차원 레이아웃에서 사용되며, 행(row) 또는 열(column) 중 하나의 방향으로 요소들을 정렬하는 데에 최적화되어 있습니다. 따라서 2차원 레이아웃(주로 행과 열의 위치를 한 번에 설정)에 특화되어 있는 grid보다 배우고 사용하기가 쉽습니다.
행과 열이 헷갈리신다면 한글단어는 잊으시고, row는 가로줄, column은 세로줄이라고 이해하시길 권장드립니다.
대부분 개발문서에서는 한글단어를 사용하지 않습니다.
- Flex 컨테이너 - 요소에 display: flex 속성을 적용함으로써, 그 요소는 컨테이너가 되고, 그 안의 자식 요소들이 아이템으로 변환됩니다.
- Flex 아이템 - Flex 아이템들은 컨테이너에 적용한 정렬 속성들로 인해 자동 정렬됩니다. align-self 속성을 통해서 각 아이템은 컨테이너에 적용된 속성을 일부 덮어쓸 수 있습니다.
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
.flex-container {
background-color: lightgray;
display: flex;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
}
컨테이너 요소 flex-container와 아이템요소 flex-item을 3개 생성하였습니다.
display: flex를 속성을 적용함으로써, 컨테이너 내의 아이템들은 기본적으로 row(가로 방향)로 나란히 배치됩니다.
3. 활용
flex 레이아웃에서는 컨테이너에 적용하는 속성과 아이템에 적용하는 속성이 구분됩니다.
화면을 구현할 때에는
- 컨테이너에 속성을 적용하여 아이템들을 자동 정렬한 후
- 필요한 경우, 각 아이템에 속성을 적용해서 덮어주는 방식을 활용합니다.
3-1. 컨테이너에 적용하는 속성
flex-direction
아이템들을 정렬할 주 축(main axis)을 결정합니다. 가로(row) 또는 세로(column)의 형태들 중에 선택합니다.
row (기본값) | 왼쪽에서 오른쪽으로 row를 형성합니다. |
row-reverse | 오른쪽에서 왼쪽으로 row를 형성합니다. |
column | 위에서 아래로 column을 형성합니다. |
column-reverse | 아래에서 위로 column을 형성합니다. |
row(기본값)
.flex-container {
background-color: lightgray;
display: flex;
flex-direction: row;
}
column
.flex-container {
background-color: lightgray;
display: flex;
flex-direction: column;
}
XXX-reverse 값을 주게 되면 1,2,3의 위치가 각각 3,2,1의 위치로 바뀝니다.
flex-wrap
이 속성은 아이템들이 컨테이너의 크기를 벗어났을 때 한 줄에 모두 표시될 것인지, 여러 줄로 나누어서 표시될 것인지 결정합니다.
nowrap (기본값) | 한 줄에 표시됩니다. |
wrap | 필요에 따라 여러 줄로 나뉩니다. |
wrap-reverse | 필요에 따라 여러 줄로 나뉩니다. 줄의 순서가 반대로 됩니다. |
nowrap(기본값)
.flex-container {
background-color: lightgray;
display: flex;
width: 50px;
flex-wrap: no-wrap;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
width: 10px;
}
wrap
.flex-container {
background-color: lightgray;
display: flex;
width: 50px;
flex-wrap: wrap;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
width: 10px;
}
3. justify-content
이 속성은 주 축(main axis)을 따라 아이템들의 정렬 방식을 설정합니다.
flex-start | 아이템들이 컨테이너의 시작점 쪽으로 정렬됩니다. |
flex-end | 아이템들이 컨테이너의 끝점 쪽으로 정렬됩니다. |
center | 아이템들이 컨테이너의 중앙에 정렬됩니다. |
space-between | 아이템들 사이에 동일한 간격이 배치되며, 양끝 아이템은 컨테이너의 시작점과 끝점에 위치합니다. |
space-around | 각 아이템 양쪽에 동일한 간격이 배치됩니다. 컨테이너와 양끝 아이템 사이의 간격은 아이템과 아이템 사이의 간격의 절반입니다. |
space-evenly | 각 아이템 사이, 그리고 컨테이너와 아이템 사이의 간격이 모두 동일합니다. |
flex-start
.flex-container {
background-color: lightgray;
display: flex;
justify-content: flex-start;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
}
flext-end
.flex-container {
background-color: lightgray;
display: flex;
justify-content: flex-end;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
}
center
.flex-container {
background-color: lightgray;
display: flex;
justify-content: center;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
}
space-between
.flex-container {
background-color: lightgray;
display: flex;
justify-content: space-between;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
}
space-around
.flex-container {
background-color: lightgray;
display: flex;
justify-content: space-around;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
}
space-evenly
.flex-container {
background-color: lightgray;
display: flex;
justify-content: space-evenly;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
}
align-items
이 속성은 교차 축(cross axis)을 따라 아이템들의 정렬을 결정합니다.
stretch (기본값) | 아이템들이 컨테이너를 채울 때까지 늘어납니다. |
flex-start | 아이템들이 교차 축의 시작점에 정렬됩니다. |
flex-end | 아이템들이 교차 축의 끝점에 정렬됩니다. |
center | 아이템들이 교차 축의 중앙에 정렬됩니다. |
baseline | 아이템들이 텍스트 기준선에 따라 정렬됩니다. |
stretch(기본값)
.flex-container {
background-color: lightgray;
height: 150px;
display: flex;
align-items: stretch;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
}
flex-start
.flex-container {
background-color: lightgray;
height: 150px;
display: flex;
align-items: flex-start;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
}
flex-end
.flex-container {
background-color: lightgray;
height: 150px;
display: flex;
align-items: flex-end;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
}
center
.flex-container {
background-color: lightgray;
height: 150px;
display: flex;
align-items: center;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
}
baseline
.flex-container {
background-color: lightgray;
height: 150px;
display: flex;
align-items: baseline;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
}
3-2. 아이템에 적용하는 속성
align-self
이 속성은 아이템 자신의 교차 축(cross axis) 정렬을 설정합니다. 따로 값을 명시하지 않으면 아이템이 속한 컨테이너의 align-items 속성이 기본값으로 적용되며 align-items의 5가지 값 중 하나로 덮어쓸 수 있습니다.
target 클래스를 만들어서 세 번째 요소에 적용해 준 후 속성을 설정하겠습니다.
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item target">3</div>
</div>
.flex-container {
background-color: lightgray;
height: 150px;
display: flex;
align-items: baseline;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
align-self: flex-start
}
.target {
background-color: purple;
align-self: flex-end;
}
마지막 요소에만 flex-end를 설정했습니다.
flex-basis
아이템의 초기 크기를 설정합니다.
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item target">3</div>
</div>
.flex-container {
background-color: lightgray;
display: flex;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
}
.target {
background-color: purple;
flex-basis: 200px;
}
마지막 요소에만 flex-basis를 200px로 설정했습니다.
flex-grow
컨테이너에 빈 공간이 있을 때 각 아이템이 차지할 빈 공간을 비율로 설정합니다. 기본값은 0입니다.
하나의 아이템에 1을 주게 되면 나머지 아이템은 모두 기본값인 0이므로 해당 아이템이 빈 공간을 모두 차지하게 됩니다.
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item target">3</div>
</div>
.flex-container {
background-color: lightgray;
display: flex;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
}
.target {
background-color: purple;
flex-grow: 1;
}
마지막 요소에만 flex-grow 1을 적용했습니다.
flex-shrink
컨테이너에 아이템이 모두 들어갈 공간이 부족할 때 각 아이템이 줄어드는 비율을 설정합니다. 기본값은 1입니다.
1보다 큰 경우 컨테이너가 좁아짐에 따라서 다른 아이템들보다 더 많이 작아집니다.
0을 주게 되면 아이템이 전혀 줄어들지 않습니다.
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item target">3</div>
</div>
flex-shrink: 2
.flex-container {
background-color: lightgray;
display: flex;
width: 300px;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
width: 200px;
}
.target {
background-color: purple;
flex-shrink: 2;
}
마지막 요소에만 flex-shrink 2를 설정했습니다.
flex-shrink: 0
.flex-container {
background-color: lightgray;
height: 150px;
display: flex;
align-items: baseline;
}
.flex-item {
background-color: cornflowerblue;
padding: 10px;
margin: 5px;
}
.target {
background-color: purple;
flex-shrink: 0;
}
마지막 요소에만 flex-shrink 0을 설정했습니다.
flex
flex로 flex-basis, flex-grow, flex-shrink 속성 중 한 개 이상을 동시에 설정할 수 있습니다.
flex: 0 1 200px; /* flex-grow | flex-shrink | flex-basis */
4. 반응형 레이아웃 - 미디어 쿼리
flex 레이아웃은 반응형 웹 디자인에서 특히 유용합니다.
큰 기기에서는 요소들을 가로(row)로 정렬하고, 가로길이가 짧은 작은 기기에서는 세로(column)로 정렬해주어야 하는 경우가 많습니다. 이럴 때는 미디어 쿼리를 사용해서 flex-direction을 변경해 주면 됩니다.
.flex-container {
display: flex;
flex-direction: row; /* 기본 방향 */
}
@media (max-width: 600px) {
.flex-container {
flex-direction: column; /* 화면이 600px 이하가 되면 column 축으로 변경 */
}
}
'프론트엔드 HTML CSS JAVASCRIPT' 카테고리의 다른 글
[HTML, CSS] 하트 만드는 방법 - before, after (0) | 2023.12.28 |
---|---|
[HTML, CSS] transform, transition으로 요소 이동 및 변형시키는 방법 / 동적인 효과(애니메이션) (0) | 2023.12.28 |
[HTML, CSS] 스크롤바 생성 overflow (auto, scroll, hidden) (2) | 2021.04.01 |
[HTML, CSS] 기본적인 페이지 레이아웃(layout) 잡기 네이버 클론코딩 (2) - flex, grid 레이아웃 (2) | 2020.03.28 |
[HTML, CSS] box-sizing 속성 / 테두리도 크기에 포함시키기 (0) | 2020.03.22 |