-
Flex Panel Gallery 🎫Web/JS30 2020. 9. 21. 18:02반응형
Flex의 여러 속성들을 살펴보고, 직접 다뤄보는 예제였다.
Flex를 사용하면서도 항상 뭔가 아리송한 점이 많았는데, 조금 정리된 듯한 느낌.
아직도 헷갈리는 점들이 좀 있기 때문에, 나중에 따로 더 시간을 내서 공부해야 될 것 같다.
Flex와 Grid는 CSS의 핵심이기 때문에 꼭 시간을 내서 공부를 해야 할 듯.
아래와 같이 5개의 그림이 있는데, 그 중 하나의 패널을 클릭하면 여러 transition이 발생하게끔 해야 했다.
일단 처음에는 이런 식으로 5개의 패널들이 세로로 나열되어있다.
<div class="panels"> <div class="panel panel1"> <p>Hey</p> <p>Let's</p> <p>Dance</p> </div> <div class="panel panel2"> <p>Give</p> <p>Take</p> <p>Receive</p> </div> <div class="panel panel3"> <p>Experience</p> <p>It</p> <p>Today</p> </div> <div class="panel panel4"> <p>Give</p> <p>All</p> <p>You can</p> </div> <div class="panel panel5"> <p>Life</p> <p>In</p> <p>Motion</p> </div> </div>
이들을 가로로 나열하기 위해서는 container를 flex container로 만들어줘야 한다.
.panels { display : flex; }
그러면, 아래와 같이 변한다.
이는 flex 아이템의 'flex-basis'라는 속성 때문인데,
기본값으로 자기가 가진 content의 영역만큼만 자리를 차지하게 되어있기 때문이다.
저 5개의 패널들이 남은 영역을 골고루 나눠가지게 만들어 주자.
.panel { display : flex; flex : 1; justify-content : center; flex-direction : column; }
일단, panel을 flex container로 만들어 준 이유는
panel의 내부 요소들도 flex 속성을 이용하여 나열할 것이기 때문.
여기서 'flex'라는 속성이 보이는데, flex 속성은 flex-grow, flex-shrink. flex-basis를 한 번에 설정할 수 있게 해준다.
저 3개의 속성은 굉장히 연관 관계가 깊기 때문에, 종종 flex를 사용하여 한 번에 설정하곤 한다.
a.
flex-basis는 아이템이 차지할 기본 영역의 크기를 설정한다.
flex-basis의 값으로는 우리가 width, height에 사용하는 각종 단위들을 가진 값이 들어갈 수 있다.
기본값은 auto이며, 해당 아이템의 width값을 사용하게 된다.
만약 아이템의 기본 width를 따로 설정하지 않으면
당연히 해당 아이템이 가진 content의 크기만큼 flex-basis가 설정된다.
참고로, flex-basis에 content라는 값도 있는데, 이는 해당 아이템이 가진 content의 크기를 의미하며
아이템의 기본 width를 따로 설정하지 않은 경우와 완전히 동일하다.
b.
flex-shrink는 박스 크기가 유연하게 줄어들도록 할 것인가에 관한 속성.
flex-basis보다 작아질 수 있는지를 설정한다. 1 이상이면 박스가 유연성을 가져서 flex-basis보다 작아진다.
기본값은 1. 만약 0으로 세팅하면, 크기가 flex-basis보다 작아지지 않기 때문에
고정폭을 가진 아이템을 쉽게 만들 수 있다.
c.
flex-grow는 박스 크기가 유연하게 늘어나도록 할 것인가에 관한 속성.
아이템들의 기본 flex-basis를 제외한 여백 부분을 flex-grow에 지정된 숫자의 비율만큼 나눠 갖는다.
기본값은 0이며, 박스 크기가 전혀 늘어나지 않는다.
참고로, 'flex-basis를 제외한 여백'을 나눈다는 의미이기 때문에
만약 아이템들의 flex-grow를 전부 동일하게 1로 설정해도, flex-basis부분은 다를 수 있다는 걸 명심할 것.
flex-basis말고 나머지 부분이 동일하다는 의미.
그래서 "flex : 1 0 auto;" 라고 하면
flex-grow는 1, flex-shrink는 0, flex-basis는 auto로 설정하겠다는 의미가 된다.
위에서 flex : 1이라고 했으니까, flex-grow만 설정되어 모든 panel들이 남은 여백을 골고루 나눠가지게 된다.
justify-content는 좌우 정렬을 어떻게 할 것인가에 관한 속성.
flex-direction은 flex 아이템들의 정렬 방향을 의미하므로, panel 내부의 글자들이 세로로 나열된다.
panel의 내부 요소들도 중앙 정렬을 해준다.
.panel > * { display : flex; flex : 1 0 auto; align-items : center; justify-content : center; }
참고로, 위의 사진은 "flex : 1 0 auto;"를 지정하기 전의 사진.
지정하고 난 후에는 위, 중앙, 아래의 글자들이 전부 동일한 영역을 차지해서 글자들이 위 아래로 뚝뚝 떨어지게 된다.
그 다음은 애니메이션을 넣어줄 차례.
일단 위 아래의 글자들은 transformY를 이용하여 화면 바깥으로 숨길 것이다.
그리고, 특정 패널을 클릭하면 해당 패널의 크기가 커지면서 위아래에서 글자가 튀어나오게 할 예정.
그래서, 일단 글자를 숨겨주고, 패널에 'open-active'라는 class가 붙으면 글자가 튀어나오게끔 속성을 붙여준다.
.panel > *:first-child { transform : translateY(-100%); } .panel.open-active > *:first-child { transform : translateY(0); } .panel > *:last-child { transform : translateY(100%); } .panel.open-active > *:last-child { transform : translateY(0); } .panel.open { font-size: 40px; flex : 5; }
open 클래스가 붙은 패널은 글자 크기가 40px로 커지고, 패널 크기는 5의 비율만큼 커짐.
이제는 자바스크립트로 이벤트 설정을 해 줄 차례.
const panels = document.querySelectorAll('.panel'); function toggleOpen() { this.classList.toggle('open'); } function toggleActive(e) { if(e.propertyName.includes('flex')) { this.classList.toggle('open-active'); } } panels.forEach(panel => panel.addEventListener('click', toggleOpen)); panels.forEach(panel => panel.addEventListener('transitionend', toggleActive));
일단은 특정 panel을 클릭하면 toggleOpen함수가 실행되도록 하였는데
toggleOpen함수는 해당 panel에 'open'이라는 클래스를 붙여주는 함수이다.
만약 addEventListener에서 함수를 붙일 때 toggleOpen()이라고 붙여주게 되면
'()'는 해당 함수를 바로 실행하겠다는 의미이므로, 페이지가 load될 때 바로 한 번 실행되니까 주의.
그리고 클릭이벤트의 transition(해당 패널이 커지는)이 끝나고 나면
해당 패널에 'open-active'라는 클래스를 붙여줘야 한다.
'open-active'는 위에서도 설명했듯이 글자가 튀어나오는 transition을 가진 클래스.
이 때 transitionend 이벤트가 발생하는 요소를 console.log로 찍어보면 다음과 같이 두 개의 요소가 나온다.
바로 panel의 flex-grow 속성과 자식 요소의 font-size에서 발생하는데,
우리는 이 중에서 panel을 골라서 이벤트 리스너를 붙여줘야 한다.
참고로, flex-grow 속성은 chrome에서는 flex-grow라는 이름을 가지는데,
safari에서는 속성 이름이 그냥 'flex'이다.
그래서, 이 두 경우를 모두 커버해주기 위해 "속성명이 'flex'를 포함하는 요소"를 찾아주면 된다.
function toggleActive(e) { // console.log(e.propertyName); if(e.propertyName.includes('flex')) { this.classList.toggle('open-active'); } }
마지막으로, CSS Flexbox를 공부하는 데에 도움이 될 만한 사이트 두 개.
1. flexbox.io : 지금 내가 공부하고 있는 'Javascript30'과 동일한 방식의 프로젝트.
하루에 하나씩 flexbox 예제들을 20일동안 공부한다. 물론 한 번에 몰아들어도 되고.
강의 진행자도 동일한 'Wes Bos'. 나중에 flexbox 공부할 때 한 번 들어봐야 될 듯.
2. 1분코딩 : 1분 코딩에서 포스팅 한 flexbox에 관한 글. 정리를 깔끔하게 잘 해놔서 큰 도움이 된다.
반응형'Web > JS30' 카테고리의 다른 글
Array Cardio Day 2 🎈 (0) 2020.10.30 Type Ahead ⌨ (0) 2020.09.25 Array Cardio Day 1 🎈 (0) 2020.09.21 Update CSS variables with JS 🎨 (0) 2020.09.20 CSS + JS Clock ⏱ (0) 2020.09.20