본문 바로가기
css

JavaScript를 활용하여 디스플레이를 사용하는 CSS 전환 구현: 없음

by code-box 2022. 2. 15.
반응형

CSS는 디스플레이를 사용하는 전환을 기본적으로 애니메이션화할 수 없습니다: 없음. 가시성(숨김 및 높이: 0)을 혼합하여 "충분히 가깝게" 만들 수 있습니다. 대부분의 경우 이러한 솔루션이 적합하지만 디스플레이를 사용하는 것과 완전히 같지는 않습니다: 없음.

이 게시물은 디스플레이를 트리거하는 CSS 전환과 함께 없음: JavaScript를 사용하는 CSS 속성을 포함하지 않음.

우리가 만들고 있는 것

단추를 클릭하면 불투명도가 1에서 불투명도 0으로 전환되는 상자를 만든 다음 전환이 완료되면 초기 디스플레이 속성에서 JavaScript를 사용하여 표시하지 않습니다. 최종 결과는 다음과 같습니다.

코드

 

다음은 위에 표시된 애니메이션 전환을 구현하기 위한 코드입니다.

<!DOCTYPE html>
  <html>
    <head>
      <meta charset="UTF-8" />
            <link href="/src/app.css" />
                  <script src="/src/app.js" defer></script>
  </head>

  <body>
                        <div id="box" class="box"></div>
    <div>
                                <button id="toggler">Toggle visibility</button>
    </div>
  </body>
</html>
/** app.css */

.box {
    opacity: 1;
    height: 100px;
    width: 100px;
    background: lightblue;
    margin-bottom: 20px;
    transition: opacity 1s;
}
.box--hidden {
    opacity: 0;
}
/** app.js */

const toggler = document.getElementById("toggler");
const toggleBox = document.getElementById("box");
const isHidden = () => toggleBox.classList.contains("box--hidden");

toggleBox.addEventListener("transitionend", function () {
    if (isHidden()) {
          toggleBox.style.display = "none";
    }
});

toggler.addEventListener("click", function () {
    if (isHidden()) {
          toggleBox.style.removeProperty("display");
          setTimeout(() => toggleBox.classList.remove("box--hidden"), 0);
    } else {
          toggleBox.classList.add("box--hidden");
    }
});

작동 방식

 

우리의 코드는 CSS 클래스 .box를 토글 버튼 클릭 시 숨겨서 상자의 불투명도를 0으로 설정합니다. .box 클래스에는 상태 간의 전환을 애니메이션화하는 전환 속성이 있습니다.

/** app.css */

.box {
    opacity: 1;
    height: 100px;
    width: 100px;
    background: lightblue;
    margin-bottom: 20px;
    transition: opacity 1s;
}
.box--hidden {
    opacity: 0;
}

.box 클래스와 .box-hidden 클래스에는 화면표시 속성이 없습니다. 이 속성은 JavaScript 내에서 설정됩니다.

우리의 스크립트는 전환 이벤트가 박스에서 발생할 때 실행되는 콜백을 포함합니다. 상자에 .box-hidden 클래스가 포함되어 있으면 상자의 CSS가 없음으로 설정되며, 전환 애니메이션이 완료되면 상자를 숨깁니다.

toggleBox.addEventListener("transitionend", function () {
    if (isHidden()) {
          toggleBox.style.display = "none";
    }
});
 

전환 종료 시 발생하는 클릭 핸들러에서 상자가 현재 숨겨져 있는지 확인합니다. 숨겨져 있으면 디스플레이가 제거됩니다. 앞서 언급한 콜백에 의해 적용된 스타일이 없는 경우 상자 숨김 클래스를 제거하기 전에 0초 시간 초과를 설정합니다. 0초 타임아웃이 없으면 브라우저는 전환 없이 상자를 즉시 렌더링합니다. 이것의 모든 이유를 이해하는 것은 중요하지 않지만, 단지 이것이 경합 조건이 아니라 브라우저가 단일 스레드인 것과 관련이 있다는 것을 알아두세요. 즉, 브라우저가 먼저 업데이트를 렌더링할 기회를 가져야 한다는 것을 의미합니다.

반대로 상자에 .box-hidden 클래스가 없으면 콜백이 이를 적용합니다.

toggler.addEventListener("click", function () {
    if (isHidden()) {
          toggleBox.style.removeProperty("display");
          setTimeout(() => toggleBox.classList.remove("box--hidden"), 0);
    } else {
          toggleBox.classList.add("box--hidden");
    }
});

권장 사항: 대신 라이브러리를 사용하십시오.

이걸 읽으면서 코드가 취약해 보인다고 생각한다면 나도 네 말에 동의해. HTML, CSS, JS는 서로 긴밀하게 연결되어 있으며 클래스 이름을 업데이트해야 할 경우 3개의 파일 모두에서 변경해야 합니다.

 

그 애니메이션은 또한 흥미로운 방법으로도 깨달을 수 있습니다. 예를 들어, 0초 전환이 있는 경우 전환은 종료됩니다. 이벤트가 발생하지 않음, 즉 디스플레이를 의미합니다. 아무것도 적용되지 않습니다.

이러한 애니메이션을 손으로 연결하는 대신 애니메이션을 실용적으로 만드는 라이브러리를 사용하는 것을 고려해 보십시오. jQuery의 .fadeToggle() 메소드는 단일 줄의 코드를 사용하여 이 포스트에서 구현한 것과 유사한 전환을 만듭니다. Alpine.js와 Vue를 사용하면 전환 애니메이션의 각 단계에 서로 다른 CSS 클래스를 적용할 수 있습니다. 많은 프런트 엔드 프레임워크에서는 애니메이션이 종료된 후 화면표시에 의존하지 않고 DOM에서 요소를 완전히 제거할 수 있습니다. 요소를 숨기려면 요소가 없습니다.

프로젝트 내 의존성의 수를 줄이는 것은 가치 있는 노력이지만, 때때로 그들의 편리함이 그들을 포함시킬 가치가 있게 한다.

댓글