상황 설명 및 해결 방법


https://cdpn.io/pen/debug/xmjRNo

https://cdpn.io/pen/debug/xmjRNo

CSS의 transition 속성은 요소의 상태 변화에 따른 시각적인 변화를 점진적으로 보여주기 위해 사용한다. 그러나 display 속성이 none에서 block 으로 변경될 때는 transition 속성을 사용해서 이 변화를 표현할 수 없다.

display: none 속성은 렌더 트리에서 요소를 완전히 제거하여 화면에서 사라지게 만들고, 이로 인해 어떠한 CSS 속성도 적용되지 않는다. 렌더 트리에서 사라지면 요소의 상태 변화를 추적할 수 없기 때문에 transition 변화가 시작되는 지점 역시 찾을 수 없다.

이 문제는 2가지 방법으로 해결할 수 있다.

  1. animation + display 사용 : animation 속성은 요소의 상태 변화와 상관없이 애니메이션 실행
  2. transition + visibility 사용 : visibility 속성은 렌더 트리/공간은 유지한 채 화면에서만 숨김

function Accordion() {
  const [showDetail, setShowDetail] = useState(false);
  // ...
  return (
    <div
      className={classnames("transition-all ease-linear duration-200", {
        "invisible max-h-0 opacity-0 -mb-[13px]": !showDetail,
        "max-h-[150px]": showDetail,
      })}
    >
      <NoticeEntries />
    </div>
  );
}

요소 숨김 방식 차이점


렌더 트리 리플로우 리페인트 이벤트 핸들러 DOM 트리
display: none 제외 발생 발생 비활성 유지
visibility: hidden 유지 발생 안함 발생 비활성 유지
opacity: 0 유지 발생 안함 발생 활성 유지
  1. display: none
  2. visibility: hidden
  3. opacity: 0