CSS: Flexbox 완벽정리
Flexbox가 개발되기 이전에는 Position / Float / Table 을 이용해서 레이아웃을 만들곤 했습니다. 하지만 이러한 방법은 복잡해서 시간이 많이 걸리고, 또 이 방법만으로는 완벽하게 구현하지 못하는 기능들이 있었습니다. 그래서 등장한 것이 바로 Flexbox입니다. Flexbox는 컨테이너 박스와 그 안에 있는 아이템들을 행과 열에 자유자재로 배치 시킬 수 있게 해주는 유용한 도구입니다. Flexbox를 잘 이해하면 웹사이트의 레이아웃을 아주 쉽게 구성할 수 있습니다.
*** 참고: Float ***
float는 원래 이미지와 텍스트가 공존하는 경우, "이미지"와 "텍스트"의 관계를 어떻게 규정하고 배치할지 결정하기 위해 만들어졌습니다. 예를 들어 float: left;의 경우, 이미지를 왼편에 배치하고, 텍스트는 이미지 이외의 공간에, 이미지를 감싸도록 배치하겠다는 의도가 담겨있습니다. 그 외에도 float: center;와 float: right;의 속성값들이 존재합니다.
과거 CSS에 레이아웃 세팅 기능이 없을 땐, 사람들이 float를 이용해서 박스들을 좌우로 정렬하고, 또 각 박스 안의 아이템들을 좌우로 배치하는데 이용했습니다. 하지만 위에서 언급했듯이, 이는 원래 float의 순수 목적이 아닌, 편법이라고 보시면 됩니다. 간혹 아직도 float을 사용해 레이아웃을 만드는 방법에 대해 가르치는 학원 선생님들이 계신 거 같아 적어보았습니다.
< FlexBox 란? >
>>> Flexbox는 크게 2가지 개념만 이해하시면 됩니다.
1. 중심축(main axis)과 중심축에 수직이 되는 반대축(cross axis)이 있다는 사실과,
2. 중심축의 container 박스와 그 container 박스 안에 들어있는 item들이 각각의 속성값들을 갖는다 것입니다.
먼저, 중심축(main axis)과 반대축(cross axis)에 대한 개념부터 확인해보겠습니다. flexbox에는 중심축과 반대축이 있습니다. 예를 들어 수평선 x축과 수직선 y축이 있다고 가정할 때, flexbox는
- x축을 중심축으로 설정하면, 자연스럽게 y축이 반대축이 되고,
- y축을 중심축으로 설정하면, 반대로 x축이 반대축이 되는 관계입니다.
즉, 본인이 중심축을 수평으로 설정하냐, 수직으로 설정하냐에 따라서 반대축이 바뀐다고 이해하시면 됩니다.
flexbox에는 container 박스에 적용되는 속성 값들이 존재하고, 또 그 container 박스 안에 존재하는 각각의 item들에 적용할 수 있는 속성 값들이 존재합니다.
먼저, container 박스에 적용할 수 있는 속성값들로는,
◆ display
◆ flex-direction: 정렬할 방향을 지정합니다.
>>> row (default) / row-reverse / column / column-reverse
◆ flex-wrap: Flex 요소들을 한 줄 또는 여러 줄에 걸쳐 정렬합니다.
>>> nowrap (default) / wrap / wrap-reverse
◆ flex-flow: 다음의 속성들을 간략히 하는 속성입니다. flex-direction과 flex-wrap
>>> <flex-direction> <flex-wrap>
◆ justify-content: Flex 요소들을 중심축선 상에서 정렬합니다.
>>> flex-start(default) / flex-end / center / space-between / space-around / space-evenly
◆ align-items: Flex 요소를 반대축선 상에서 정렬합니다.
>>> flex-start /flex-end / center / baseline / stretch(default)
◆ align-content: 반대축선 상에 여분의 공간이 있는 경우, Flex container 사이의 간격을 조절합니다.
>>> flex-start / flex-end / center / space-between / space-around / space-evenly / stretch (default)
다음, items의 속성값들로는,
◆ order: Flex 요소의 순서를 지정합니다.
>>> <integer> (... -1, 0 (default), 1, ...)
◆ flex-grow
◆ flex-shrink
◆ flex
◆ align-self: 지정된 align-items 값을 무시하고 Flex 요소를 반대축선 상에서 정렬합니다.
>>> flex-start / flex-end / center / baseline / stretch
< Flexbox 사용방법 >
>>> display: flex
~~~~~~~~~~~~~~
먼저, container의 display를 flex로 설정합니다.
.container {
display: flex;
}
>>> flex-direction: row / row-reverse / column / column-reverse
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
다음으로 중요한 container 레벨의 속성 값인 flex-direction을 설정합니다.
- 기본값은 row (열)입니다.
- row는 왼쪽에서 오른쪽으로 가는 방향입니다.
- 즉, 행과 열 중, "열"에 해당합니다.
반대로, flex-direction: row-reverse; 라고 설정하면, 오른쪽에서 왼쪽으로 배치 방향이 뒤바뀝니다. 현재까지는 중심축이 열입니다.
한편, 중심축을 세로방향, 즉 행으로 바꾸고 싶을 경우, flex-direction: column; 으로 설정하면 됩니다. 기본적인 방향은 위에서 아래로 내려가는 방향입니다. 반대로 flex-direction: column-reverse;는 배치 방향이 아래에서 위로 올라가는 방향입니다.
>>> flex-wrap: nowrap / wrap / wrap-reverse
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
기본값은 flex-wrap: nowrap;입니다. 일렬로 정렬된 아이템들이 많아서 작은 화면 사이즈에서는 너무 비좁게 일렬로 줄지어 늘어서 있을 때 사용하면 좋습니다.
flex-wrap: wrap; 은 container 박스 안에 일렬로 늘어선 아이템들이, 화면 크기가 작아 본연의 크기를 제대로 구현할 수 없을 때, 자연스럽게 다음 열로 넘어가도록 배열하는 방법입니다.
flex-wrap: wrap-reverse;는 flex-wrap: wrap; 처럼 아이템들이 열을 바꾸며 자연스럽게 이어지는 것은 똑같지만, 그 진행 방향이 반대됨을 의미합니다.
>>> flex-flow:
~~~~~~~~~~~~
flex-flow는 flex-direction과 flex-wrap 속성값을 하나로 축약해서 나열할 수 있는 속성입니다. 예를 들어 flex-flow: column nowrap;과 같이 사용되는데, 전자의 column은 flex-direction의 속성값이고, 후자의 nowrap은 flex-wrap의 속성값입니다.
이제까지는 무엇을 중심축으로 설정할지, 또 그 방향은 어떻게 나열할지에 대해서 설정하는 단계였다면, 지금부터는 중심축에 존재하는 아이템들을 어떻게 배치하고 정렬할 것인지에 대해 설정하는 방법들에 대해 알아보겠습니다.
>>> justify-content: flex-start / center / flex-end / space-around / space-evenly / space-between
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*** justify-content는 중심축(main axis)에서 아이템들을 어떻게 배치할 것인지 결정해줍니다.
justify-content의 기본값은 flex-start로, 처음부터 나열하도록 돼 있습니다. 즉, 수평축이 중심축이라면 왼쪽 상단에서 오른쪽 상단으로 배열되고, 반대로 수직축이 중심축인 경우, 왼쪽 상단에서 왼쪽 하단으로 배열되도록 되어 있습니다.
justify-content: flex-end;는 아이템의 순서는 그대로 유지한 상태로 전체가 오른쪽에 붙도록 배치됩니다. 중심축이 수직일 경우, 똑같이 아이템의 순서는 유지되면서 전체가 밑에 붙도록 배치됩니다.
justify-content: center;는 아이템들을 중앙에 몰아서 배치해줍니다.
justify-content: space-around;는 각각의 아이템 박스들 주변에 동일한 스페이스를 부여합니다. 이 경우, 맨 왼쪽과 맨 오른쪽 박스의 경우, 스페이스가 한 번씩만 반영돼 공간 여백이 작은 반면, 중간에 위치한 박스들은 모두 좌/우 박스의 스페이스을 한 번씩 적용 받아, 총 2배의 공간 여백이 생기게 됩니다. 만약 아이템 박스들 사이의 공간이 일정하게 분배되도록 하고 싶은 경우, justify-content: space-evenly;를 사용하면, 모든 아이템 박스들 사이의 여백 공간의 동일하게 분배됩니다.
justify-content: space-between;은 맨 왼쪽과 맨 오른쪽 아이템은 각각의 경계에 고정한 채, 그 사이에 위치한 아이템 박스들만 공간을 똑같이 분배하는 방법입니다.
*** 한편, align-items는 반대축(cross axis)에서 아이템들을 배치하는 속성값입니다. 중심축이 row이고 아이템들이 일렬로 쭉 나열돼 있는 상태에서, 아이템들의 위치를 수직적으로 화면 중심에 배치하고 싶을 경우, align-items 속성을 사용하시면 됩니다.
>>> align-items: flex-start /flex-end / center / baseline / stretch(default)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
만약 일렬로 나열돼 있는 아이템들 중, 하나에 padding값이 할당돼 있어 크기가 달라 정렬이 안 맞는 경우에, align-items: baseline;을 활용할 수 있습니다. align-items: baseline;은 아이템 안에 있는 "텍스트"들의 위치를 다른 아이템들과 모두 동일해지도록 만들어주는 기능을 합니다.
>>> align-content: flex-start / flex-end / center / space-between / space-around / space-evenly / stretch (default)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
align-content는 justify-content와 동일한 속성값들을 모두 사용할 수 있습니다. justify-content가 중심축의 아이템들을 배치한다면, align-content는 반대축의 아이템들을 지정하게 됩니다. 즉, flex-wrap: wrap; 이면서 동시에 나열된 아이템들이 많아, 아이템들이 여러 줄로 나뉘어 이어진다면, align-content를 사용해서 열이 바뀐 채 나열돼 이어지는 아이템들의 배치에 변화를 줄 수 있습니다.
예를 들어, flex-wrap: wrap;이라 세 줄까지 연이어 나열된 아이템들이 있다고 가정했을 때, align-content: space-between;은 첫 째 줄과 셋 째 줄은 맨 위와 맨 아래에 붙인 채, 가운데 줄만 중앙에 위치하도록 배치합니다. 만약 align-content: center;로 지정하면, 세 줄로 이어진 아이템들이 모두 딱 달라붙은 채 중앙에 배치되게 됩니다.
*** !important ***
align-content는 여러 줄들 사이의 간격을 지정하며, align-items는 컨테이너 안에서 어떻게 모든 요소들이 정렬하는지를 지정합니다. 한 줄만 있는 경우, align-content는 아무런 효과를 보이지 않습니다.
이번에는 아이템에 들어가는 속성값들에 대해서 알아보겠습니다.
>>> order:
~~~~~~~~~~
속성값으로는 정수인 integer가 부여될 수 있습니다. 음수와 0, 양수 모두 가능합니다. 예를 들어 container 안에 item1, item2, item3이 위치한다고 했을 때,
.container {
display: flex;
}
.item1 {
order: 2;
}
.item2 {
order: 1;
}
.item3 {
order: 3;
}
이런 식으로 order라는 속성을 이용해 각각의 아이템 위치를 바꿔줄 수 있습니다. 하지만 실제 작업에서 사용되는 경우는 거의 없습니다.
>>> flex-grow:
~~~~~~~~~~~~~
기본값은 0;입니다. 원래 아이템들은 자신에게 부여된 크기를 유지합니다. 예를 들어 div.item의 width: 40px; height:40;인 경우, 화면 크기가 줄어 어쩔 수 없이 div.item의 크기를 줄여야하는 상황에서만 아이템의 크기들이 눌려서 작아집니다. 하지만 flex-grow를 사용하면, 화면 크기와 상관없이 부여된 숫자의 비율만큼 화면을 꽉 채우게 됩니다.
.item1 {width:40px;height40px;}
.item2 {
width:40px;
height:40px;
flex-grow: 2;
}
.item3 {width:40px;height40px;}
나머지 아이템들은 전부 40px; 박스를 유지하지만, .item2 박스는 item1과 item3의 박스 크기인 40px*2=80px; 을 제외한 나머지 전체 공간을 꽉 채우게 됩니다.
.item1 {
flex-grow: 1;
}
만약, item1에 flex-grow: 1;을 추가로 지정해줄 경우, 고정값인 .item3의 40px;을 제외한 나머지 공간에 한해 .item1와 .item2가 각각 1:2의 비율로 화면을 분할해 채워지게 됩니다.
>>> flex-shrink:
~~~~~~~~~~~~~~
기본값은 0;입니다. flex-shrink는 화면의 크기가 작아졌을 때, 얼마의 비율로 작아질 것인지에 대해 정의합니다.
이처럼, flex-grow와 flex-shrink 는 컨테이너의 크기가 바뀌었을 때, 아이템들이 얼마나, 어떻게 더 늘어나고 줄어드는지 정의하는 역할을 합니다.
★ 유용
>>> flex-basis:
~~~~~~~~~~~~~
flex-basis는 아이템들이 공간을 얼마나 차지해야하는지 조금 더 세부적으로 명시해주는 역할을 합니다. 기본값은 auto;입니다. 예를 들어,
.item1 {
flex-basis: 60%
}
.item2 {
flex-basis: 30%
}
.item3 {
flex-basis: 10%
}
와 같이 지정한다면, 화면 크기가 변하는 것과 상관없이 각각의 아이템들이 정해진 비율에 맞춰서 크기가 변화합니다. 굉장히 유용하게 활용할 수 있는 도구입니다.
>>> align-self:
~~~~~~~~~~~~~
align-self를 이용하면, "아이템별로" 아이템의 위치를 정렬할 수 있습니다. 예를 들어 일렬로 늘어선 아이템들 중, 하나만 가운데 정렬을 하고 싶을 경우,
.item1 {}
.item2 {
align-self: center;
}
.item3 {}
이렇게 지정하면, .item2 박스만 중심축이 되는 열에서 벗어나 화면 중앙에 배치되게 됩니다.
지금까지 CSS의 꽃이라고 불리는 Flexbox의 개념과 활용방법에 대해 알아보았습니다. 보다 시각적인 도움이 필요하신 경우, 아래 사이트를 방문하시면, Flexbox에 대한 보다 자세한 설명과 사용법을 확인해보실 수 있습니다.
CSS: Flexbox의 Cheat Sheet 입니다.
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
'HTML & CSS > CSS' 카테고리의 다른 글
[CSS] 화면 가득 높이 설정 방법 (0) | 2021.08.26 |
---|---|
[CSS] 스크롤 스냅 (Scroll Snap) (0) | 2021.08.07 |
[CSS] 리셋: reset.css (0) | 2021.08.06 |
[CSS] 반응형 Navbar 제작 (w/o 부트스트랩) (0) | 2021.08.06 |
[CSS] 미디어 쿼리 Media Query (0) | 2021.07.25 |