맞춤형 아코디언과 같은 Netflix 구축

최근 CSS를 연습하기 위해 React와 Sass만 사용하여 Netflix의 Landing Page의 UI를 복제했습니다. 간단했지만 저와 같은 사람이 프런트엔드 개발을 할 수 있는 많은 학습 기회가 있었고 저는 그 도전을 즐겼습니다. 관심이 있는 경우 프로젝트에 대한 링크는 다음과 같습니다. Netflix Landing Page Clone .

이 게시물에서는 다른 많은 온라인 플랫폼에서 이미 보았을 수도 있는 섹션에 초점을 맞추고 이를 구현하는 방법을 배웁니다. 피아노가 아니라 아코디언이라고 합니다 😂.

웹 아코디언이란 무엇입니까?



접을 수 있는 콘텐츠를 관리하는 데 도움이 됩니다. 많은 양의 콘텐츠 숨기기와 표시 사이를 전환하려는 경우에 유용합니다.

이것이 제가 복제 프로젝트를 위해 구축한 것입니다.



블록 중 하나를 클릭하면 콘텐츠가 확장되어 다음과 같이 표시됩니다.



건물을 짓자 🔨



Note: For the sake of simplicity, I will use plain HTML, CSS, and Javascript to build this instead of React and Sass.



✏ 먼저 HTML로 아코디언의 구조를 만들어 봅시다.




<div class="qna">
  <button class="accordion">Question 1</button>
  <div class="panel panel-closed">
    <p>Answer of Question 1</p>
  </div>
  <button class="accordion">Question 2</button>
  <div class="panel panel-closed">
    <p>Answer of Question 2</p>
  </div>
  <button class="accordion">Question 3</button>
  <div class="panel panel-closed">
    <p>Answer of Question 3</p>
  </div>
  <button class="accordion">Question 4</button>
  <div class="panel panel-closed">
    <p>Answer of Question 4</p>
  </div>
</div>




🎨 이제 몇 가지 기본 스타일을 추가하고 CSS로 기본값을 재설정합니다.




/* Centers horizontally */
.qna{
  max-width: 500px;
  margin: 0 auto;
}
/* Button default resets */
button{
  border: none;
  outline: none;
  cursor: pointer;
}
/* Styling the accordion buttons */
.accordion{
  width: 100%;
  background-color: #303030;
  color: #fff;
  font-size: 20px;
  padding: 18px 20px;
  margin-bottom: 1px;
  text-align: left;
  /*  To push the plus sign to the right  */
  display: flex;
  justify-content: space-between;
  align-items: center;
}
/* adding the "plus" sign (+) */ 
.accordion::after{
  content: '\02795';
  font-size: 20px;
  color: #fff;
}

.panel{
  background-color: #303030;
  color: #fff;
  margin-bottom: 4px;
  overflow: hidden;
}
.panel > p {
  font-size: 20px;
  padding: 10px 20px;
}
.panel-closed{
  max-height: 0;
  overflow: hidden;
}




⚙ Javascript로 기능 추가



우리는 우리가 원하는 것을 대충 적어야 합니다. 누군가가 아코디언 버튼을 클릭하면 다음과 같이 되기를 원할 것입니다.
  • 아코디언 아래 패널 표시(아래로 슬라이딩 애니메이션 포함)
  • "더하기 기호(+)"를 "십자 기호(x)"와 같은 다른 것으로 변경합니다
  • .
  • 다른 버튼을 클릭하면 이전 패널이 자동으로 닫힙니다.

  • 하나씩 코딩해 봅시다.

    여기에서 클래스panel-open를 추가하고 누군가 아코디언 버튼을 클릭할 때 패널 div에서 클래스panel-closed를 제거할 수 있으며 유사하게 버튼을 다시 클릭할 때 반대 작업을 수행할 수 있습니다. 이미 닫힌 클래스가 있으므로 열린 클래스를 작성해 보겠습니다.

    .panel-open{
      max-height: 700px;
    }
    


    javascript에서 클래스 추가 및 제거 로직 코딩:

    let accordion = document.getElementsByClassName("accordion");
    const totalAccordions = accordion.length;
    
    for (let i = 0; i < totalAccordions; i++) {
      accordion[i].addEventListener("click", (e) => {
        let panel = e.target.nextElementSibling;
    
        if (panel.classList[1] === "panel-closed") {
          panel.classList.add("panel-open");
          panel.classList.remove("panel-closed");
        } else {
          panel.classList.add("panel-closed");
          panel.classList.remove("panel-open");
        }
      });
    } 
    


    이렇게 하면 아코디언 버튼의 클릭 이벤트를 기반으로 max-height 속성이 토글됩니다.

    이제 더하기 기호를 십자 기호로 변경하기 위해 활성 상태의 아코디언 버튼에 다른 클래스를 추가할 수 있으며 javascript는 동일한 클릭 이벤트 핸들러 함수에서 이를 처리합니다.

    /* active class for accordion, adds the "cross sign (x)" */
    .accordion-active::after {
      content: "\274C";
    }
    


    js 코드를 추가한 후:

    let accordion = document.getElementsByClassName("accordion");
    const totalAccordions = accordion.length;
    
    for (let i = 0; i < totalAccordions; i++) {
      accordion[i].addEventListener("click", (e) => {
    
      // toggle the class 'accordion-active' on accordion button
      e.target.classList.toggle("accordion-active");
    
        let panel = e.target.nextElementSibling;
    
        if (panel.classList[1] === "panel-closed") {
          panel.classList.add("panel-open");
          panel.classList.remove("panel-closed");
        } else {
          panel.classList.add("panel-closed");
          panel.classList.remove("panel-open");
        }
      });
    } 
    


    이를 수행하는 보다 깔끔한 방법은 추가 및 제거 대신 토글을 사용하는 것입니다.

    let accordion = document.getElementsByClassName("accordion");
    const totalAccordions = accordion.length;
    
    for (let i = 0; i < totalAccordions; i++) {
      accordion[i].addEventListener("click", (e) => {
    
      // toggle the class 'accordion-active' on accordion button
      e.target.classList.toggle("accordion-active");
    
        let panel = e.target.nextElementSibling;
    
        if (panel.classList[1] === "panel-closed") {
          panel.classList.toggle("panel-open");
        } 
      });
    } 
    




    🌈 부드러운 슬라이드 다운 애니메이션 추가:



    패널의 슬라이딩을 부드럽게 보이게 하기 위해 transition 를 찾는 max-height 속성을 추가할 수도 있습니다. panel 클래스에 추가하기만 하면 됩니다.

    .panel{
      transition: max-height .33s cubic-bezier(.5,0,.1,1);
    }
    


    다음은 위의 cubic-bezier 곡선과 선형 전환을 시각적으로 비교한 것입니다.



    전환 속성을 추가한 후의 모습은 다음과 같습니다.



    우리는 거의 끝났지만 뭔가 빠졌습니다. 예, 이전 패널은 새 패널을 열 때 자동으로 닫히지 않습니다.

    이를 위한 함수를 만들어 보겠습니다. 이 함수는 현재 열려 있는 패널을 인수로 사용하고 다른 아코디언을 열 때 열려 있는 다른 모든 패널(있는 경우)을 닫습니다.

    const closeAllExcept = (pan) => {
      for (let i = 0; i < totalAccordions; i++) {
        let panelToClose = accordion[i].nextElementSibling;
        if(panelToClose !== pan){
           accordion[i].classList.remove("accordion-active");
           panelToClose.classList.remove("panel-open");
        }
      }
    }
    


    이제 이 함수를 호출해야 합니다. 아래는 최종 자바스크립트 코드입니다. 이제 accordion-active에도 클래스를 토글할 수 있는 컨트롤이 있으므로 if 블록 내에서 closeAllExcept 클래스 토글 코드를 이동했음을 알 수 있습니다.

    let accordion = document.getElementsByClassName("accordion");
    const totalAccordions = accordion.length;
    
    for (let i = 0; i < totalAccordions; i++) {
      accordion[i].addEventListener("click", (e) => {
        let panel = e.target.nextElementSibling;
    
        if (panel.classList[1] === "panel-closed") {
          e.target.classList.toggle("accordion-active");
          panel.classList.toggle("panel-open");
          closeAllExcept(panel);
        }
      });
    } 
    
    const closeAllExcept = (pan) => {
      for (let i = 0; i < totalAccordions; i++) {
        let panelToClose = accordion[i].nextElementSibling;
        if(panelToClose !== pan){
           accordion[i].classList.remove("accordion-active");
           panelToClose.classList.remove("panel-open");
        }
      }
    }
    


    만세, 이제 완벽하게 작동합니다 😍



    이거 만드는거 재밌었지, 그치? 😎 놀면서 놀고 싶다면 여기 이 프로젝트에 대한 내Codepen 링크가 있습니다. 재미있게 읽으셨다면 댓글로 알려주시거나 Twitter에서 저에게 연락주세요 🙌

    📖 리소스


  • w3 Schools Docs
  • Netflix India Website
  • An amazing tool to visualize cubic beziers
  • 좋은 웹페이지 즐겨찾기