혼자 독학할 때 가장 힘들었던 부분이 이 CSS Flexbox였다.
대충 어떤 개념인지는 빠르게 파악을 했는데, 내 마음대로 박스가 정렬되고 배열이 안됐음.
대체??? 왜애애??
내가 CSS에 참 재능이 없구나 싶었음 ㅋㅋㅋㅋㅋ
그래서 겸사겸사 복습겸 정리를 좀 해보자.
혼자 독학했을 때보단 코드스테이츠를 통해 복습을 하니, 이해력이 조금 늘지 않았을까??
대충 내가 이해한 flexbox는 flex박스 공간을 만들어서 그 안에 flexItem을 늘어놓는 방식을 말한다.
라고 말하면 ㄹㅇ flexbox의 힘을 개무시하는게 될 수 있는데,
고정적인 px(픽셀) 방식으로 웹페이지를 구성하면 글씨크기나 컨텐츠의 크기가 고정이 된다.
최근 스마트폰, 태블릿, 컴퓨터 등 다양한 매체로 인터넷 접근이 가능해지면서 크기가 고정된 컨텐츠는 박살이 난다.
PC의 웹페이지를 스마트폰으로 본 사람은 알겠지만, 매우 불편하고 크기도 작다.
flexbox는 화면 크기에 따라 box의 크기를 조절해주고 item의 배열을 조절해준다.
예시
상기 이미지를 보면 화면크기 (우측 상단 참고)에 따라 박스 크기가 달라지고 item들의 크기도 다 달라짐을 볼 수 있다. 어느 크기 밑으로 내려가면 좌우로 펼쳐져 있던 아이템들이 아에 세로로 내려가는 것을 볼 수 있다. 이게 flexbox의 힘이다. 그 덕에 화면 크기에 따라 다른 웹페이지 화면을 볼 수 있다. 최근엔 모바일, 태블릿 위주로 웹페이지를 개발한다고도 한다.
선언 방법은
셀렉터 {
display: flex;
}
혹은
셀렉터 {
display: inline-flex;
}
flexbox는 기본적으로 수직으로 분할된다. 방향을 바꿔주면 수평으로도 분할할 수 있다.
flex는 박스에 선언을 해준다. 이 선언해준 박스를 flex 컨테이너라고 부른다.
html
<div class="box"> <div class="item">Item1</div> <div class="item">Item2</div> <div class="item">Item3</div> </div>
css
* { box-sizing: border-box; } .item { width: 100px; height: 100px; margin: 10px; border: 1px solid black; }
codepen으로 간단한 div 박스들을 만들어보았다. div는 block이기 때문에 각자 작동해서 아래로 내려간다.
결과
여기에 flex를 적용해보자. 아까 말했듯 부모태그인 .box에 선언을 해주면 된다.
.box {display: flex;}
결과
div는 분명 block인데 옆으로 넘어갔다. f12로 분석을 좀 해보자
박스 크기
flex를 선언한 box의 크기가 저렇게 됐다. 위 아래로 쭉 늘어난 box가 아닌 아이템 크기만큼 가로로 길게 가져갔음
상기 html을 복사해서 같은 div를 2개 만들어주면 flex의 디폴트 형태를 알 수 있을 것이다.
저 화면은 현재 2개의 박스와 각 박스 안에 3개의 item이 있는 상황이다.
이런 상황인거다 즉 display:flex는 기본적으로 세로 배치가 됨을 알 수 있다.
item들이 가로로 늘어져 있는건 조금 더 지켜보자.
하여튼 display: flex를
display: inline-flex;
로 고치면 box가 이동한다.
div박스가 가로로 배치된다.
상기 box사진을 보면 display:flex는 컨테이너 배치에 대한 요소를 포함함을 알 수 있다.
내부 item을 정렬하기 위해 다양한 속성이 필요한데,item1,2,3을 보면 가로로 배치됨을 알 수 있다.
flex-direction은 이 item 배열에 대한 속성으로 기본값은 row다.
예시를 좀 보자. display:flex로 지정해서 ㄱㄱ
row
row-reverse
column (item이 총 6개면 차이점을 알기 힘들어서 컨테이너를 1개 삭제함)
column-reverse
box안쪽 글씨를 보면 item 순서를 알 수 있다.
reverse는 거꾸로 배치되어 있다. 그 부분에 주의하자.
margin에 여러 값을 붙이면 자동으로 top left bottom right 을 넣어줌을 알고 있다.
border의 경우 픽셀, 선종류, 색
flex도 마찬가지다
flex는 grow, shrink, basis 가 붙는다.
이게 뭔 개소리냐면
grow : 팽창 지수, 기본값은 0이다. 아이템이 3개 있으면 3을 최대값으로 비율이 나눠짐
이를테면 grow를 2로 지정하면 컨테이너에 2/3을 차지한다.
item1 class에 target을 추가한 후 grow를 2로 지정했다.
item2, 3이 1/3을 차지하고 나머지 2/3을 item1이 차지함을 알 수 있다.
shrink : 수축 지수, 기본값은 1임. 얘도 grow처럼 비율로 조정된다. 얼마나 줄어들 수 있는지에 대한 기본 크기다.
문제는 이게 basis 속성에 따른 비율이라 실제 크기를 예측하기 어렵다고 한다. 그래서 보통 1로 둔다고함.
basis : 박스의 기본크기 지정이다. grow나 shrink에 의해 늘어나거나 줄어들기 전에 가지는 기본크기다.
grow가 0일 때, basis크기를 지정하면 그 크기가 유지 된다. 즉 최소 크기라는 뜻으로 볼 수 있을 듯.
item1에 flex-basis를 300px로 지정해보자
grow가 0임에도 300px크기가 basis로 지정됐기 때문에 유지됨을 알 수 있다.
만약 item2에 grow를 2로 지정하면 어떻게 될까?
item1은 300px을 유지 (grow가 0이므로 더 늘어나지 않음) item2는 2/3의 크기를 가져가야 하므로 item3를 미칠듯이 줄여서 그 비율을 맞췄다.
다만 flex에 item이 워낙 많고 복잡해지면 basis를 항상 보장하지 않고 변한다고 한다.
부모박스, 즉 컨테이너에 justify-content를 적용하면 item들을 수평정렬 할 수 있다.
flex-direction은 아이템을 어떻게 쌓을까 라는 고민이라면,
justify-content는 쌓은 아이템의 정렬을 어떻게 할까 라는 고민이라 할 수 있겠다.
flex-start : 컨테이너 시작부분부터 정렬한다. 아마 기본값으로 사료됨
flex-end : 컨테이너 끝부분에 정렬한다. flex-direction의 reverse와 헷갈릴 수 있으니 아래 사진을 보면
item1,2,3 순서대로 정렬됨을 알 수 있다. flex-direction의 reverse 속성은 거꾸로 쌓는거기 때문에 좌측부터 3,2,1로 쌓인다.
center : 중앙배치한다.
space-between : item별 공간을 일정간격으로 동일하게 유지해준다.
item이 3개라 잘 몰라볼 수 도 있겠지만... ㅋㅋㅋㅋ 하여튼 간격을 동일하게 벌려주고 flex컨테이너 처음과 끝을 다 먹는다.
space-around : between과 비슷하지만 flex 컨테이너 경계면까지도 그 간격을 동일하게 만들어 준다.
item1과 2 사이가 꽤 넓어 보이는데 item1의 좌측 여백의 정확히 2배다. 이는 item1의 우측, item2의 좌측도 같은 간격으로 벌어지기 때문이다.
space-evenly : around보다 더 확실하게 간격을 똑같이 만들어 준다.
flex 컨테이너의 경계면, item의 경계 모두 동일 간격임을 알 수 있다.
justify-content가 수평 정렬이면 align-items는 수직 정렬이다. 이걸 어떻게 보여줄까 고민했는데, 후...
위 예시들도 컨테이너 크기를 정해두고 border해놨으면 참 보기 편했을거란 생각이 든다.
컨테이너 크기를 400px로 제한하고 해보자 (width, height 둘 다)
stretch : 기본값이다. 아이템들이 수직축 방향으로 끝까지 늘어난다. .item의 크기를 없애보면 확연하다.
flex-start : 컨테이너 시작부분부터 쌓아준다. stretch와 다르게 아이템을 늘리지 않는다.
flex-end : 컨테이너 끝부분에 정렬한다. align-items는 수직 정렬이므로 아래부터 정렬한다고 보면 된다. 가시성을 위해 item의 크기를 다시 늘려줬다.
center : 중앙정렬한다.
baseline : 아이템들을 텍스트 베이스라인 기준으로 정렬한다.
그 외에도 flex-wrap이라든가 align-contents같은 다양한 속성이 많다. 천천히 정리하도록 하겠음.