STYLESHEET/STYLE- 참고

[참고] display:none일 때, transition 불가

dev_jiwon 2023. 2. 3.
display:none 일때는, transition으로 효과를 넣어도 생각한대로 작동되지 않는다.

원인은?

transition을 이용한 애니메이션의 특징

transition은 이전 프로퍼티의 상태와 이후 프로퍼티의 상태를 비교해서 그 차이를 부드럽게 이어준다. 일반적으로 숫자 연산 가능한 속성에 사용한다.

 

opactiy: 1~0.1로 변화

 

top: 0~100px로 변화

 

그러나 display와 visibility는 숫자로 연산이 안된다. 따라서 이 둘은 transition 효과도 불가능.

 

주요 렌더링 경로 Critical Rendering Path

인터넷 브라우저가 화면 상에 코드를 그릴 때 내부적으로 여러 단계를 거친다. 이 일련의 단계들을 중요 렌더링 경로(Critical Rendering Path)라고 부른다. 관련 내용은 4단계로 나눌 수 있다.

 

이미지 출처 : https://dev.to/codesensei/critical-rendering-path-39m

- Dom, CSSOM 트리 생성: 파싱한 HTML과 CSS를 이용해 document object model과 CSS object model을 각각 생성한다

- 렌더링 트리 생성: 앞 단계에서 생성한 트리 정보를 바탕으로, '화면에 표시'할 요소들의 정보를 정리해 렌더링 트리를 만든다.

- 레이아웃(혹은 리플로우): 요소가 실제 화면(뷰포트) 상에 너비, 높이, 위치가 어떻게 될 것인지 계산(만)한다. (아직 화면에 보이지 않음)

- 페인트: 실제로 화면에 픽셀을 그림

 

display:none 요소는 화면 상에 아예 보이지 않기 때문에 렌더링 트리에서 누락되게 된다. 따라서 렌더링 트리 X, 레이아웃 계산 X, 페인트 X

 

display:block이 되었을 때가 되어야 비로소 렌더링 트리에 들어가게 되고 그제야 레이아웃과 페인트가 일어난다. transition애니메이션을 이용하려면 none 상태의 opacity와 block 상태의 opacity 값의 차이를 비교할 수 있어야 하는데, none 상태의 opacity는 애초에 존재한 적이 없으니(렌더링 트리X), 상태를 비교할 값이 없어 transition 애니메이션을 사용할 수 없는 것이다.

 

 

해결방법

transition이 아니라, keyframe animation 활용

사라질 때 애니메이션이 필요없는 경우에만 추천

transition이 비교할 초기값이 없어 애니메이션이 불가능 한 반면에 키프레임 애니메이션은 초기값을 유저가 직접 할당하고 실행시키기 때문에 동작이 가능하다.

 

but, 문제점은 있다

display:none → block 으로 가는 애니메이션은 초기값 설정으로 애니메이션 구현이 가능하지만

display:block → none 으로 가는 애니메이션은 불가능하다.

none이 되었을 때 렌더 트리에서 바로 삭제해 버리기 때문에, 애니메이션을 재생할 틈이 없다.

 

 

display:none을 안쓰고 구현

none 속성이 아니라 다른 방법으로 화면 상에서 보이지 않게 처리한다면 transition을 활용한 애니메이션도 활용 가능하다. 다양한 여러 방법들이 가능하겠지만, 대체적으로 적용할 수 있는 방법이 2가지 있다.

 

1. display 대신에 visibility 이용

display:none과 달리 visibility:hidden은 화면에 보이지 않아도 공간을 차지하고 있다. 위의 렌더링 과정을 이용해 다시 말하자면, visibility는 3단계 레이아웃 계산을 끝마쳤다는 것과 같은 의미이다. 따라서 visibility:hidden 상태와 visibility:visible 상태를 서로 비교할 수 있고, transition 애니메이션을 사용할 수 있다.

 

- visibility:hidden 처리된 요소는 display:none처럼 접근성 트리에도 삭제된다.
   (애니메이션을 이용할 생각이라면 display:none보다 나을 수 있다)
- transition-property를 all로 해야만 적용된다.

 

2. pointer-event 활용

display:none을 왜 굳이 사용했을까? 
'화면 상에 안 보이고, 높이값도 안 차지하고 그 자리에 클릭 이벤트도 안 걸렸으면 좋겠다' 의  생각은 아니었을까?

화려한 애니메이션 같은 것이 들어가는 경우가 아닐 때에는, 화면 상에서 보이지 않게만 처리할 거라면 그냥 opacity:0으로 지정하고 마우스 클릭 이벤트를 없애도 된다. 이때, 사용할 수 있는 CSS 속성이 바로 pointer-events이다.해당 요소에 pointer-events 속성을 none으로 지정하면, 화면 상에서 클릭했을 때 해당 영역은 잡히지 않고 크롬 개발자 도구에서도 클릭으로 잡을 수 없다.다시 화면상에 나타날 때에는 pointer-events: auto;로 지정하면 된다.

 

 

See the Pen display none animation by JIWON CHOI (@jiwonch) on CodePen.

참고

https://songsong.dev/entry/css-display-none-%EC%95%A0%EB%8B%88%EB%A9%94%EC%9D%B4%EC%85%98-%EC%88%98%EC%A0%95%ED%95%98%EA%B8%B0

 

css display none 애니메이션 오류 수정하기

오늘의 문제 display:none; display:block; 에 transition 애니메이션이 적용되지 않는다! See the Pen display none animation1 by ylem76 (@ylem76) on CodePen. 메뉴를 마우스 오버했을 때 하위 메뉴가 보이고, 마우스 아웃하

songsong.dev

 

댓글