본 포스팅은 💻 유데미 Advanced CSS and Sass강좌 사이트를 공부하면서 정리한 내용입니다.
Flex Layout 속성은 Container에 대한 속성과 Container 안에 있는 Item에 대한 속성으로 나뉜다.
Flex Layout을 위해 가장 처음으로 해야 할 일이 바로 display 정의이다.
display: flex
: Block 특성의 Flex Container를 정의한다.display: inline-flex
: Inline 특성의 Flex Container를 정의한다.기본적으로 display: flex
만 입력했다면 row(수평) 방향으로 정렬된다. (기본값)
수직 방향으로 정렬하려면 flex-direction
을 column으로 설정하면 된다.
순서를 뒤집고 싶다면 row-reverse
나 column-reverse
를 사용하면 된다.
✅ 필수 : 여기서
주축(main-axis)
과교차축(cross-axis)
의 개념을 잘 알고 넘어가야 한다.
- row는 수평이 주축이고 수직이 교차축이다.
- column은 수직이 주축이고 수평이 교차축이다.
주축(main-axis)의 정렬 방법을 설정한다. direction이 row라면 수평에 대한 정렬방법이고, column이면 수직에 대한 정렬방법이 된다. 일반적으로 row이기 때문에 여기서는 row라고 가정하고 설명을 진행하겠다. 그래서 그런지 justify-content 하면 가로축 정렬로 잘못 일반화하는 경우도 많다.
justify-content: center
: Items를 가운데 정렬
justify-content: flex-start
(기본값) : Items를 시작점으로 정렬
justify-content: flex-end
: Items를 끝점으로 정렬
justify-content: space-between
: 시작 Item은 시작점에, 마지막 Item은 끝점에 정렬되고 나머지 Items는 사이에 고르게 정렬됨
justify-content: space-around
: Items를 균등한 여백을 포함하여 정렬
교차 축(cross-axis)에서 Items의 정렬 방법을 설정한다. Items가 한 줄일 경우
주로 사용한다.
align-items: stretch
(기본값) : Container의 교차 축을 채우기 위해 Items를 늘린다. 아래는 2번째 박스만 크기를 크게 주고 싶었지만 나머지도 전부 커졌다. 이는 stretch가 기본값이기 때문이다.
align-items: center
: Items를 교차축을 기준으로 가운데 정렬
align-items: flex-start
: Items를 교차축을 기준으로 시작점 정렬
align-items: flex-end
: Items를 교차축을 기준으로 끝점 정렬
align-items: baseline
: Items를 문자 기준선에 정렬. 아래 그림은 box 4의 글자 크기를 크게한 후 baseline 정렬한 결과이다.
교차 축(cross-axis)에서 Item의 정렬방법을 설정한다. align-itmes
가 Items를 한꺼번에 설정하는 거였다면, align-self
는 개별적으로 정렬이 가능한 방법이다.
속성값은 align-items와 동일하게 stretch, flex-start, flex-end, center, baseline이 있다. 기본 값은 Container의 align-items 속성을 상속받은 값이 된다.
아래 그림은 align-items를 center로 하고, 박스 4번만 align-self로 flex-end를 설정하였을 때 결과이다.
order은 Item의 순서를 설정한다. Item에 숫자를 지정하는데 숫자가 클수록 순서가 밀리게 된다. 기본 값은 0이고, 음수 값도 가능하다.
아래 그림은 박스 4번을 order: -1
로 설정한 결과이다. 다들 기본 값이 0이며 4번만 가장 앞선 -1이기 때문에 4번이 가장 앞에 위치한 것을 확인할 수 있다.
Item의 증가 너비 비율
을 설정한다. 숫자가 크면 더 많은 너비를 가진다. 다만 Item이 가변 너비가 아니거나, 값이 0일 경우 효과가 없다.
아래 그림은 박스 전부를 flex-grow: 1
로 설정한 경우이다. 전체적으로 마진을 제외하고 동일한 비율로 가득 차지한 것을 볼 수 있다.
이번에는 나머지는 다 flex-grow: 1
인데, 박스 2만 flex-grow: 2
로 설정한 경우이다. 1, 3, 4, 5가 동일한 비율에 1이라면 2번만 2라는 비율을 차지하고 있는것을 볼 수 있다.
1, 2, 3, 4는 flex-grow를 지정하지 않고, 5만 flex-grow를 1로 지정했을때 결과이다. 5가 아닌 것들은 최소한 크기만을 갖고, 5번만 전체 크기를 갖게 된다. 이러한 방법은 실제 많이 쓰이는 방법 중 하나이다(✍).
💻 추가적으로
flex: 1
로 작성하면 이것은flex-grow: 1
과 의미가 같다. (아래에서 자세히 다룬다)
Item의 (공간 배분 전) 기본 너비를 설정한다. 값이 auto일 경우 width, height 등의 속성으로 Item의 너비를 설정할 수 있다. 하지만 단위 값이 주어질 경우 설정할 수 없다.
첫번째 경우는 flex-grow
를 1이라고만 설정 했을 때이다. 이럴 경우 flex-basis
는 자동으로 auto가 기본값이 된다. 아래 그림을 보면 알겠지만 1:1:2이지만 글자 개수가 달라서 그런지 비율이 맞지가 않는다.
.i2 {
flex-grow: 1;
}
.i3 {
flex-grow: 1;
}
.i4 {
flex-grow: 2;
}
두번째 경우는 flex: 1
이라고만 지정한 경우입니다. flex: 1
은 flex-grow: 1
인거는 맞습니다만 flex-basis
는 auto가 아닌 0이 됩니다. 따라서 위와 비교했을 때 박스 크기가 정확히 1:1:2가 되는 것을 확인할 수 있다.
.i2 {
flex: 1;
}
.i3 {
flex: 1;
}
.i4 {
flex: 2;
}
flex-basis를 단위로 지정도 가능하다. (px이나, %나 rem 등...)
Item이 감소하는 너비의 비율을 설정한다. 숫자가 크면 더 많은 너비가 감소한다. Item이 가변 너비가 아니거나, 값이 0일 경우 효과가 없다. (기본값은 1)
만약 flex-shrink
를 아무것도 지정하지 않은 상태에서 화면 너비를 줄이면 동일하게 줄어들 것이다. 이번에는 감소 너비를 2:1로 지정했다면? 🤔 2로 지정한게 1보다 2배가량 많이 줄어들게 된다.
근데 신기하게도 flex-shrink
는 다 1로 설정했는데 줄어드는거는 5부터 줄어든 다음에 2가 줄어든다. (flex-grow
특성상 이게 먼저 줄어드는게 맞는거 같기도 하다... 솔직히 아직 잘 모르겠다🤦♂️)
.i2 {
flex-basis: 300px; // 기본 너비 300px
flex-shrink: 1;
}
.i5 {
flex-grow: 1; // 나머지 전체 공간 차지
flex-shrink: 1;
}
참고로 i2에서 flex-shrink
를 0으로 지정하면 화면이 줄어들어도 i2는 줄지 않는다.
flex-grow(증가 너비), flex-shrink(감소 너비), flex-basis(기본 너비)부터 해서 참 쉽지 않은거 같다. 보통은 이 3가지 속성을 flex로 합쳐서 많이 쓴다. 🚨 주의할 점은 위에서도 말했다싶이 flex-basis는 기본값이 auto인데, flex에서 그 값을 생략할 경우 0이 적용된다.
.item {
flex: 1 1 20px; /* 증가너비 감소너비 기본너비 */
flex: 1 1; /* 증가너비 감소너비 */
flex: 1 20px; /* 증가너비 기본너비 (단위를 사용하면 flex-basis가 적용됩니다) */
}
flex container 설정 중에 flex-wrap
을 빼먹은게 있었다. 자주는 안쓰이지만 필요할때는 쓰여서 밑에다가 따로 빼놨다. Items가 많아지면 줄바꿈을 하고 싶을것이다. 하지만 flex-wrap의 기본값이 nowrap이라서 아무런 설정을 하지 않는다면 한줄에 표시됩니다.
flex-wrap: nowrap
(기본값) : 무조건 한 줄 표시flex-wrap: wrap
: 일정 크기까지 떨어지면 여러줄로 표시교차 축(cross-axis)의 정렬 방법을 설정(특히 2줄 이상일 때). align-itmes가 한 줄일때 쓰였다면 align-content는 2줄 이상일때 쓰인다.
아래는 container 크기를 충분히 크게하고 2줄일때 align-content를 space-between을 적용한 결과입니다. 보는것처럼 첫째줄과 두번째줄이 상당히 떨어져 있는 것을 볼 수 있습니다.
.container {
background-color: #ccc;
padding: 10px;
display: flex;
height: 500px;
flex-wrap: wrap;
align-content: space-between;
}
쉽지 않네요..😂😂 막상 프로젝트를 진행하다보면 이거 어떻게 했었지? 저거 어떻게 했었지? 하면서 하나씩 해보다가 잘 된다 싶으면 넘어가는게 태반이라서 이번 기회에 제발 알고 쓰자는 마음에서 정리해봤습니다.
유데미 강의랑 아래 참고 사이트를 많이 참조했습니다.
참고 사이트