Flexbox 개요
- 만약 블럭요소에 대해서 가로 정렬을 하고 싶다면 display 요소를 쓰는데 그렇게 하면 inline-block으로 해야하는데 빈공간이 생김
- 그래서 이에 대해서 가로 정렬이 inline-block도 애매함, float에서 left를 쓰게 되면 붙긴 하지만 container가 짤리게 됨
- 그럴 때 display: flex 속성을 주면 가로 정렬을 할 수 있음, 가로 정렬을 유지하면서 container에 맞게됨, 이처럼 유연하게 작동하는게 flexbox임
- flexbox의 경우 container와 item이 함께 있을 때 1차원 기준으로 아이템을 정렬하는데 용이한 속성임
- 예시
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</div>
.container {
border: 5px dashed orange;
display: flex;
}
.item {
width: 50px;
height: 50px;
background-color: paleturquoise;
border: 3px solid blue;
}

용어 flex container, flex item, main axis, cross axis
- Flexbox는 1차원 정렬이기에 아이템을 감싸는 container와 item이 반드시 필요함
- flex container의 경우 내부의 여러가지 아이템을 담고 있고 부모 태그임, 그리고 flex item의 경우, 내부의 정렬을 위해 담아놓은 아이템들임(아이템은 여러가지 일 수 있음)
- 이를 구분하는 이유는 각각 property에 적용할 속성들이 다르기 때문임
- 그리고 item이자 container도 될 수 있음
- 그리고 main axis(주축), cross axis(교차축) 주로 main axis는 가로 cross axis는 세로로 기준을 잡음
- 경우에 따라서 이 축들을 바꾸고 달라질 수도 있음
Container display
- flexbox의 경우 요소의 내부 아이템들을 1차원으로 정렬할 떄 쓰는 것임, Container 기준으로 display를 flex로 바꿔서 처리할 수 있는 것임
- 이는 블록 & 인라인 요소들끼리와의 관계만 따지는 것과는 다르게 처리할 수도 있음(mdn 내에서는 display-outside라고 함)
- display-inside 즉, 내부의 아이템들에 대한 요소들을 어떻게 처리할 것인지 관리하는 것임
- inline & block / flex & grid 등 좀 다르게 받아들여야함(같은 display에서 처리하더라도)
- 이럴 땐
display: inline-flex
와 같이 쓰면 외부의 요소들은 inline으로 처리하면서 내부 아이템들을 flex로 처리하는 것
- 제일 중요한 건 이 display는 container에 직접 줘야지 처리할 수 있음
- 참고자료
- 참고자료
Container flex-direction
- 이제 계속 볼 flex 속성의 경우 Container에서 적용해서 처리하는 속성인지, Items들에 대해서 적용해서 처리하는 속성인지 구분해야함
- flex-direction의 경우는 Container에서 쓰는 속성임, 이는 주축 및 방향을 지정하여 처리하는 속성임
- 가로 정렬이 된 경우 main-axis가 가로가 될 것임(cross-axis는 세로)
- 하지만 이 때 direction을 변경해서 세로 정렬을 하면 main-axis는 세로가 될 것임(cross-axis는 가로)
- 이 때 방향을 바꾸는 말은 왼쪽에서 오른쪽으로 가는 것을 오른쪽에서 왼쪽으로 가게끔 주축의 방향(정방향 or 역방향)도 바꿀 수 있음(주축의 위치뿐 아니라)
- 그래서 사용할 수 있는 경우가 총 4가지임, 기본값은
row
임
- row-reverse는 가로 방향을 반대로, column은 수직방향으로, column-reverse는 수직 방향인데 아래에서 위로
- 이처럼 주축의 방향, 주축의 위치를 바꿀 수 있음
- 예시
.container {
height: 500px;
border: 5px dashed orange;
display: flex;
flex-direction: row-reverse;
}



Container flex-wrap, flex-flow(shorthand)
- flew-wrap 역시 Container에 사용하는 속성임 flex-item을 강제로 한 줄에 배치할지, 여러 행으로 나누어서 표현할지 처리하는 속성
- 여기서 기본값은 flex 속성을 준 경우, 1차원 정렬이므로 모든 아이템들이 무조건 한 줄에 들어가게됨(아무리 줄여도 한 줄로 됨)
- 하지만 강제로 한 줄에 배치될 때 item이 깨지는 것을 방지하기 위해서 flex-wrap을 쓰면 됨
- flex-wrap의 기본은 무조건 한 줄에 배치하는 것임(nowrap)
- wrap으로 지정하면 flex-item이 여러행의 걸쳐서 배치 되고 위에서 아래로 쌓임, 이는 width의 크기에 따라서 item이 자동으로 개행되서 배치됨
- 원래 item의 크기를 유지하는 목적으로 많이 쓰임
- wrap-reverse도 마찬가지인데 시작점과 끝의 기준이 반대로 됨
- 예시
.container {
height: 500px;
border: 5px dashed orange;
display: flex;
flex-wrap: wrap;
}
.item {
width: 50px;
height: 50px;
margin: 5px;
background-color: paleturquoise;
border: 3px solid blue;
font-size: 30px;
}


- flex-flow는 단축속성으로 flex-direction과 flex-wrap을 같이 쓰는 속성임
- 참고자료
- 참고자료
Item order
- 이번엔 Item에 쓰이는 속성으로 order가 있는데 순서를 배치하는 속성임
- 기본값은 0으로 코드 순서대로 배치가 되게끔 할 수 있음
- 여기서 만약 item들의 순서를 바꾸고 싶다면 HTML을 조작하지 않고 order 속성을 통해서 단위 아이템을 조정할 수 있음
- 기본은 오름차순 순으로 처리함, 이 값은 정수로 음수도 활용해서 할 수 있음
- 아래 예시와 같이 order를 주게 된다면 order를 준 값에 따라서 조정됨(마이너스인 경우 다 0이므로 맨 앞에 가고 양수인 경우 다 0이므로 맨 뒤로 감)
- 예시
.container {
height: 500px;
border: 5px dashed orange;
display: flex;
flex-wrap: wrap;
}
.item {
width: 50px;
height: 50px;
margin: 5px;
background-color: paleturquoise;
border: 3px solid blue;
font-size: 30px;
}
.item:nth-child(3) {
order: 1;
}

- 추가하고 싶은 order가 있다면 각 아이템 모두에 order를 줘서 수정할 수 있음
- 참고자료
Item flex-grow
- flex-grow의 경우 본인이 차지한 요소를 할당 가능한 공간의 차지할 수 있는 정도를 늘릴 수가 있음
- 이는 늘린만큼 더 늘어날 수도 있다는 의미임, 기본값이 0이므로 flex-grow 값을 준다면 남은 공간을 item끼리 나눠서 빈 공간을 메꿀 수 있음
- 즉, 할당 가능한 공간, 수용 가능한 공간이 있다면 그만큼 처리한다는 의미임(이는 조금이라도 값을 주면 줄바꿈이 되어도 그만큼 값이 유연하게 차리하게함)
- 예시
.container {
height: 500px;
border: 5px dashed orange;
display: flex;
flex-wrap: wrap;
}
.item {
width: 50px;
height: 50px;
margin: 5px;
background-color: paleturquoise;
border: 3px solid blue;
font-size: 30px;
flex-grow: 1;
}

- flex-grow의 경우 음수값이 아닌 0부터 그 이상의 숫자를 다양하게 사용할 수 있음(소수점도 가능)
- flex-grow 값만큼 비율을 가져서 남은 공간을 각 item들이 공간을 가져간다는 의미임
- 만약 여기서 flex-grow를 서로 다른 값으로 만든다면 빈 공간을 그 서로 다른 비율만큼 각자 할당받은만큼 공간을 차지함
- 즉, 남은 공간을 flex-grow로 설정한 비율만큼 나눠가짐(하나의 아이템만 준다면 그 하나의 아이템이 비율만큼 다 가져가는 것)
- 예시
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
.container {
height: 500px;
border: 5px dashed orange;
display: flex;
}
.item {
width: 50px;
height: 50px;
margin: 5px;
background-color: paleturquoise;
border: 3px solid blue;
font-size: 30px;
}
.item:nth-child(2) {
flex-grow: 2;
}
.item:nth-child(3) {
flex-grow: 1;
}

flex-shrink
- shrink의 경우 grow와 같은 원리이지만 반대되는 개념임
- grow의 경우 남는 공간이 있을 경우 그 남는 공간을 메꾸는데 비율상으로 정한대로 처리하는 것인 반면
- shrink의 경우, 아이템보다 Container가 작아서 아이템이 Container에 들어갈 수 없을 때, 얼마나 작아지는지 비율로 값을 처리하는 것
- 즉 이는 item들이 가지고 있는 값이 px이어도 container가 줄어든만큼 줄어들기에 이걸 얼마나 줄어들게끔 할 것인지 처리하는 것
- 기본값이 1이므로 모든 item들이 동일하게 줄어드는 것
- 마찬가지로 음수가 안되고 0부터 소수점도 가능함
- 0으로 하게 된다면 줄어들어도 그 아이템은 크기가 안 줄어들고 나머지 아이템들이 그만큼 더 작아짐
- 양수값을 주게 된다면 양수값을 준만큼 줄어드는 속도가 더 빨리 줄어들어서 그만큼 더 작아지게 되는 것임
- 이는 반대로 줄어든 영역을 나눠가진다고 생각해도 됨(그래서 grow랑 원리가 동일하다는 것)
- 예시
.container {
height: 500px;
border: 5px dashed orange;
display: flex;
}
.item {
width: 50px;
height: 50px;
margin: 5px;
background-color: paleturquoise;
border: 3px solid blue;
font-size: 30px;
}
.item:nth-child(2) {
flex-shrink: 0;
}
.item:nth-child(3) {
flex-shrink: 2;
}

Item flex-basis
- flex-basis는 flex item이 grow, shrink 되지 않았을 때의 기본 크기를 이야기함
- flex-basis를 별도로 설정하지 않으면 기본 item의 크기를 그대로 가져감
- 크기이므로 픽셀값과 상대적인 퍼센티지도 사용가능함
- 앞서 flex-grow를 할 때 요소의 크기만큼 처리가 되서 늘리더라도 공간을 차지하는데 있어서 요소의 크기가 큰 것은 큰 요소의 크기만큼 더 차지함(공간은 동일하게 나눠가져도)
- 그래서 이 때 flex-basis를 설정해서 기본값을 맞춰서 늘어난 공간과 비율을 잘 맞출 수 있음
- 이 때 0으로 설정을 하게 될 경우, 진짜 flex-grow로 늘어날 때 공간을 나눠가진 비율만큼만 커지게 됨(요소의 크기 상관없이 0이므로)
- 예시
.container {
height: 500px;
border: 5px dashed orange;
display: flex;
flex-wrap: wrap;
}
.item {
width: 50px;
height: 50px;
margin: 5px;
background-color: paleturquoise;
border: 3px solid blue;
font-size: 30px;
flex-grow: 1;
flex-basis: 100px;
}

- flex-basis를 0으로 두면 동일하게 비율을 처리하게 되는 것임, 그러면 아래와 같이 처리하게 되면 정확하게 가로 비율이 나뉘어지게 됨
- 아래 예시를 보면 결국 content-box 기준으로 5:1:3으로 나뉘어짐
- 예시
.container {
height: 500px;
border: 5px dashed orange;
display: flex;
flex-wrap: wrap;
}
.item {
width: 50px;
height: 50px;
margin: 5px;
background-color: paleturquoise;
border: 3px solid blue;
font-size: 30px;
flex-basis: 0;
}
.item:nth-child(1) {
flex-grow: 5;
}
.item:nth-child(2) {
flex-grow: 1;
}
.item:nth-child(3) {
flex-grow: 3;
}


Item flex(shorthand)
- flex의 경우 앞서 배웠던 속성, flex-grow, shrink, basis를 같이 쓸 수 있는 단축 속성임
- 3개가 필수 값은 아니라 1,2개만 작성할 수 있음(작성하지 않은 것은 자동을 initial 값으로 들어감)
- flex-grow는 0 flex-shrink는 1, flex-basis는 auto로 초기값이 들어감
- flex의 경우 근데 flex-basis가 자동으로 초기값이 auto로 들어가진 않음
- 즉, 한 개 또는 두 개의 값을 flex로 쓰게 된다면 값이 auto가 아니라 0으로 동작함을 알고 있어야함(초기값이 auto라도 0으로)
- 값을 initial, auto, none으로도 쓸 수 있음
- 참고자료
Container justify-content
- 주축을 기준으로 아이템을 어떻게 정렬할 지에 대한 속성임
- flex-start의 경우 주축이 시작되는 위치부터 정렬하는 속성임
- flex-end를 할 경우 주축이 끝나는 위치에 정렬함
- 이는 flex-direction에 따라서 그 정렬되는 위치가 다르게 될 수 있음 그래서 단순히 오른쪽 정렬 이런식으로 보면 안되고 주축을 따져야함
- column으로 방향이 바뀌면 해당 주축은 세로축이므로 세로축 기준으로 시작되는 위치와 끝나는 위치임
- center의 경우 주축을 기준으로 가운데로 옴(만약 flex-direction 변경 시, 순서가 바뀔 수 있음)
- space-between의 경우, flex-start, end에 요소가 붙어 있고 나머지 요소들은 동일한 간격으로 떨어져 있음(요소 상관없이, 사이 요소만 확실하게 줌)
- space-around의 경우, flex-start, end를 기준으로 요소 앞뒤로 동일한 여백을 줌(그래서 붙어 있지 않고 앞뒤에도 간격이 있음)
- 예시
.container {
border: 5px dashed orange;
display: flex;
justify-content: space-between;
}
.item {
width: 50px;
height: 50px;
margin: 5px;
background-color: paleturquoise;
border: 3px solid blue;
font-size: 30px;
}


Container align-items
- justify-content의 경우 주축을 기준으로 아이템을 정렬했음
- align-items의 경우 교차축을 기준으로 아이템을 어떻게 정렬해서 처리할 지에 대한 속성임
- 애초에 flex는 1차원 아이템인데 이에 대해서 교차축(cross-axis 기준으로) 어디에 둘지 처리하는 속성임
- 전체 Container 기준으로 아이템을 어디다 둘 지에 대한 처리(교차축 기준으로 정렬)
- align-items는 기본값으로 stretch인데(item에 height가 없다면 container의 height 교차축만큼 크기를 차지함)
- 만약 item에 height가 있다면 그 height만큼만 처리됨
- 이 때 flex-start의 경우 교차축의 시작점, flex-end는 교차축의 끝점에 item 리스트들이 위치하게됨
- center를 쓰면 교차축 기준으로 가운데로 들어옴
- 즉, 한 줄 자체를(flex item들을) 어디다 둘 지 처리하는 것임
- 예시
.container {
height: 400px;
border: 5px dashed orange;
display: flex;
justify-content: space-between;
align-items: center;
}
.item {
width: 50px;
height: 50px;
margin: 5px;
background-color: paleturquoise;
border: 3px solid blue;
font-size: 30px;
}
Container align-content
- 여러 줄에 대한 정렬은 align-content를 써야함
- content가 붙은 것은 여러개에 대한 정렬을 얘기함
- justify-content처럼 여러개에 대한 정렬인데 기준만 교차축(cross-axis)일 뿐임
- align-content를 통해서 교차축을 기준으로 wrap이 된 아이템들에 대해서 어떻게 정렬할 지 처리함
- flex-start는 교차축의 시작점 flex-end는 교차축의 끝점에서 처리함, center는 중간임
- 여러개이므로 space-between, space-around도 가능함, 이는 교차축 기준으로 위아래로 간격을 주는 것임(앞뒤 간격이 있거나 없거나)
- 그래서 align-items는 한 줄, align-content는 여러 줄에 대해서 정렬을 처리하는 것임
- 예시
.container {
height: 400px;
border: 5px dashed orange;
display: flex;
flex-wrap: wrap;
align-content: space-around;
}
.item {
width: 150px;
height: 50px;
margin: 5px;
background-color: paleturquoise;
border: 3px solid blue;
font-size: 30px;
}

Item align-self
- align-self는 아이템에서 쓸 수 있는 정렬임
- 그 전에 아래 예시처럼 flex-wrap의 경우 원래는 한 줄일 아이템들이 3줄 마치 3개의 Container가 있는 것처럼 작동하고 보여짐
- 그래서 align-items를 쓰게 될 때도 각 줄이 차지하는 기준으로 마치 3개의 Container안에서 위치가 조정되는 것처럼 보임
- 예시
.container {
height: 400px;
border: 5px dashed orange;
display: flex;
flex-wrap: wrap;
align-items: center;
}
.item {
width: 150px;
height: 50px;
margin: 5px;
background-color: paleturquoise;
border: 3px solid blue;
font-size: 30px;
}

- align-self의 경우, 위의 상황에서 특정 아이템만 위치를 조정할 수 있음(교차축 기준으로)
- 별도로 작성하지 않으면 align-items를 따라서 값이 처리하게 됨(한 요소만 align-items와 동일한 키워드를 바탕으로 조정할 수 있음)
- 예시
.container {
height: 400px;
border: 5px dashed orange;
display: flex;
flex-wrap: wrap;
align-items: center;
}
.item {
width: 150px;
height: 50px;
margin: 5px;
background-color: paleturquoise;
border: 3px solid blue;
font-size: 30px;
}
.item:nth-child(4) {
align-self: flex-start;
}
