HTML을 배우면서 가장 헷갈렸던 게 Flexbox 기능이다. float를 통해 이미지를 정렬하는 방법을 배우다가 flexbox를 이용하니 훨씬 편하다는 건 알겠지만... 너무 복잡하다. 기능이 많고, 또 비슷한 명령어인데도 상당히 다른 결과가 종종 나왔다. 앞으로도 계속 헷갈릴 바에 한 번 정리하는 게 마음 편할 것 같다는 생각에 작성하는 글이다.
1. Flex와 flex-direction
Flexbox는 기본적으로 부모 요소와 자식 요소로 나뉜다. display: flex를 지정하면, 해당 요소의 자식 요소들은 Flex Item이 된다. Flex Item의 부모 요소를 Flex Container라 부른다. 가장 간단한 예시부터 살펴보자.
<div style="display: flex">
<p>Hello!</p>
<img src="../img/book.jpg" style="height: 100px; width: 100px">
</div>
결과:
원래대로라면 p 태그는 block element이므로 새로운 줄에 img가 와야 한다. 그런데 div element에 display: flex 속성을 주어 flex container로 지정하니 flex item인 p 태그와 img 태그가 같은 행에 배치된다. 이는 flex item들의 정렬 방향인 flex-direction의 default value가 row로 지정되어있기 때문이다. 만약 flex-direction을 다르게 설정하면 어떻게 될까?
<div style="display: flex; flex-direction: column">
<p>Hello!</p>
<img src="../img/book.jpg" style="height: 100px; width: 100px">
</div>
결과:
이제는 열 방향으로 정렬되었다. 기본값인 row는 왼쪽에서 오른쪽으로, column은 위에서 아래쪽으로 자식 요소들을 배치한다. 만약 거꾸로 배치하고 싶다면 row-reverse 혹은 column-reverse를 쓰면 된다.
2. justify-content
flex-direction으로 정렬할 축과 방향을 지정하고 나면, 어떻게 정렬할 것인지 결정해야 한다. 이는 justify-content 속성으로 결정한다. 값들을 정리하면 다음과 같다.
flex-start: 시작점에서 정렬 (default value)
flex-end: 끝점에서 정렬
center: 중앙에서 정렬
space-between: 요소들 사이에 균일한 배치
space-around: 요소들 주위에 균일한 간격 배치
space-between은 '요소의 사이'에 공백을 두고, space-around는 개별적인 요소의 주변에 공백을 둔다.
style과 body 부분의 코드는 다음과 같다.
<style>
.container {
display: flex;
border: 2px solid black;
justify-content: space-around;
}
.item {
width: 100px;
height: 50px;
background-color: lightblue;
margin: 5px;
}
</style>
<div class="container">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
</div>
결과:
여기서 알아둘 점은 flex container의 너비는 기본적으로 flex-direction 방향으로 가능한 한 너비를 최대한 차지한다. 따라서 브라우저의 크기에 따라 flex container의 너비도 달라지고, flex item들의 정렬도 달라지게 된다. flex가 반응형 웹사이트에 최적화된 이유다. 만약 flex container의 크기를 명시하면 브라우저의 크기와 관계없이 일정하게 유지된다.
3. align-items
align-items는 flex-direction에 대해 cross axis를 기준으로 item들을 정렬한다. 값들을 정리하면 다음과 같다.
stretch: 요소들을 교차축 방향으로 확장하여 채움 (default value)
flex-start: 교차축의 시작점에서 정렬
flex-end: 교차축의 끝점에서 정렬
center: 교차축 중앙에 정렬
baseline: 요소들의 텍스트 베이스 라인 기준 정렬
(body는 동일)
<style>
.container {
display: flex;
border: 2px solid black;
justify-content: space-around;
height: 300px;
align-items: center;
}
.item {
width: 100px;
height: 50px;
background-color: lightblue;
margin: 5px;
}
</style>
결과:
flex-direction을 따로 지정하지 않았으므로 자동으로 row 방향이 주축이 된다. 그리고 교차축인 column 방향의 center로 item이 정렬된 걸 확인할 수 있다.
추가로 align-content는 item이 여러 줄일 때 정렬하는 속성이다.
4. flex-wrap
flex item들이 container 크기를 초과할 때 줄바꿈을 할지 여부를 결정한다. 값들을 정리하면 다음과 같다.
nowrap: 줄바꿈 없이 한 줄에 배치 (default value) -> item의 크기를 줄여서라도 한 곳에 넣음
wrap: 여러 줄로 나누어 배치
wrap-reverse: 줄바꿈을 반대로 하여 배치
어려운 내용은 아니니 예시는 생략. 이후부터는 flex item의 속성이다.
5. flex-grow, flex-shrink, flex-basis
flex-grow와 flex-shrink는 다른 flex item들이 갖는 값과 상대적인 비교를 한다.
<style>
.container {
display: flex;
border: 2px solid black;
justify-content: space-around;
height: 300px;
align-items: flex-start;
flex-wrap: wrap;
}
.item {
width: 100px;
height: 50px;
background-color: lightblue;
margin: 5px;
}
</style>
<div class="container">
<div class="item" style="flex-grow: 1">Item 1</div>
<div class="item" style="flex-grow: 2">Item 2</div>
<div class="item" style="flex-grow: 3">Item 3</div>
</div>
결과:
브라우저의 크기를 최소로 지정해 flex container가 충분히 작으면 각 flex item들은 똑같은 너비를 가진다. 그런데 브라우저의 크기를 늘려 flex container가 6만큼 늘어난다면, item 1은 1만큼, item 2는 2만큼, item 3은 3만큼 늘어난다. 이게 flex-grow의 의미다. flex-shrink는 반대로 줄어들 때 감소하는 값의 비율을 지정한다고 생각하면 된다.
flex-basis는 기본적으로 flex item이 갖는 크기를 지정한 뒤, 그 다음 grow나 shrink가 일어난다.
세 값을 하나하나 지정하는 대신 flex 속성으로 지정할 수 있다.
flex: <flex-grow> <flex-shrink> <flex-basis>
만약 flex item의 요소 중 하나를 1의 flex-grow, 0의 flex-shrink, 100px의 flex-basis를 지정하고 싶다면 flex: 1 0 100px 로 설정하면 된다. 이 요소는 100px로 시작해서 1의 비율로 늘어나고, 다른 item이 줄어들 때 이 요소는 줄어들지 않는다.
여기까지 포스팅한 뒤 천천히 고치고 추가해나갈 예정!
'공부 > 코딩' 카테고리의 다른 글
Git 정리 1편: 기초 개념과 사용법 (2) | 2024.10.15 |
---|---|
JavaScript 정리 1편 : 배열 메서드 (Array Method) (0) | 2024.09.06 |
HTML / CSS 정리 2편 : display, inline과 block에 대해 (0) | 2024.08.31 |
HTML / CSS 정리 1편: DOM과 HTML, 그리고 Web page (0) | 2024.08.31 |
Java 이야기 - 객체 지향 프로그래밍 (Object-Oriented Programming) (0) | 2024.08.09 |