height : auto시 transition이 적용되지 않는 문제

경이·2025년 6월 8일
post-thumbnail

📌 문제 상황

빼곡의 독서기록 페이지는 위와 같이 도서정보, 독서기간, 독서노트 등이 아코디언 UI로 구성되어 있다. 각 섹션을 클릭하면 펼쳐지고 접히는 애니메이션을 넣어 더 나은 UX를 제공하고자 했다.

이때 각 섹션은 서버로 받아온 데이터에 따라 높이가 달라진다. 예를 들어 독서기간 섹션의 경우 1회독일 경우와 다회독일 경우에 따라 보여줘야 하는 독서 기간의 개수가 달라지기 때문에 내부 콘텐츠의 길이에 따라 높이가 바뀌게 된다.

즉, 토글 영역은 height: auto 상태를 갖는다. 그래서 아래와 같이 간단하게 transition을 적용해봤다.

<section className={` ${isToggledInfo ? 'h-auto py-4' : 'h-0'} overflow-hidden transition-all duration-200`}>
  <ul>높이가 고정되지 않은 요소</ul>
</section>

하지만 토글이 열리고 닫힐 때 애니메이션이 동작하지 않았다.


원인 분석

transition은 CSS 속성이 변경될 때, 시작 상태와 끝 상태 사이를 부드럽게 연결해주는 기능이다.

예를 들어 사용자가 마우스를 호버해서 background-color가 검정색에서 회색으로 바뀔 때 transition을 주면 두 색 사이를 점진적으로 변화시킬 수 있다.

하지만 transition이 정상적으로 작동하려면 변경되는 속성의 시작 값과 끝 값이 모두 명확한 수치로 지정되어 있어야 한다.

// 0부터 200까지 점진적으로 애니메이션을 적용
height: 0px → height: 200px;

하지만 height: auto는 명확한 수치가 아니기 때문에 브라우저가 시작점과 끝점을 계산할 수 없다.

그래서 다음과 같은 경우에는 애니메이션이 동작하지 않는다:

// auto 값을 계산할 수 없으므로 애니메이션 적용 불가
height: 0px → height: auto; 

해결방법 1 - max-height 사용

가장 흔히 알려진 해결방법은 height 대신 max-height를 사용하는 방식이다.

auto는 명확한 수치가 아니라 사용할 수 없지만 max-height는 최대값만 명확히 지정하면 transition이 적용될 수 있다.

이때 중요한 포인트는 시작과 끝 두 상태 모두 max-height로 명확한 값을 지정해야 한다는 것이다.

초기에는 아래처럼 max-hh를 혼용해 transition이 적용되지 않았었다.

<section className={` ${isToggledInfo ? 'max-h-dvh py-4' : 'h-0'} overflow-hidden transition-all duration-200`}>
	<ul>높이가 고정되지 않은 요소</ul>
</section>

위 코드처럼 토글된 상태에서는 max-height, 닫힌 상태에서는 height를 사용하면

transition은 각각 max-height:nonemax-height:100dvh , height:autoheight:0 으로 인식하게 되어 애니메이션이 적용되지 않는다.

따라서 다음과 같이 max-height를 기준으로 두 상태 모두 동일한 속성에서 값을 바꿔주는 것이 핵심이다.

<section className={` ${isToggledInfo ? 'max-h-dvh py-4' : 'max-h-0'} overflow-hidden transition-all duration-200`}>
	<ul>높이가 고정되지 않은 요소</ul>
</section>

해결방법 2 - CSS Grid를 활용한 방식

또 다른 해결책은 CSS Grid의 grid-template-rows를 활용하는 방식이다. 이 방식은 콘텐츠의 실제 높이에 상관없이 행의 비율을 기준으로 크기를 변화시켜 애니메이션을 줄 수 있다. (사실 transition에서 두 상태 모두 동일한 속성에서 값을 바꿔줘야 한다는 것을 몰라서 탄생한 방식이다)

<section className={`grid ${isToggledDate ? 'grid-rows-[1fr]' : 'grid-rows-[0fr]'} transition-all duration-200`}>
  <ul className="overflow-hidden">높이가 고정되지 않은 요소</ul>
</section>

💡 결론

  • height: autoheight : 100% 는 transition이 적용되지 않는다.
  • transition은 시작과 끝 값을 명확히 계산 가능한 경우에만 동작한다.
  • 해결 방법
    1. height 대신 max-height 사용
    2. CSS Gridgrid-template-rows를 사용

✏️ 느낀점

  • HTML, CSS에 대한 깊이는 역시 많이 삽질해봐야 늘어나는 것 같다.
  • 이번 경험을 통해 transition의 동작 방식을 더 자세히 알 수 있었다.
profile
록타르오가르

0개의 댓글