display none이 transition이 안먹히는 이유

dev.tinkerbell·2020년 11월 3일
62

CSS

목록 보기
2/2
post-thumbnail

간혹 자바스크립트를 사용하여 시각적으로 요소가 보였다 안보이는 작업을 할 경우가 있었는데 초반에는 애니메이션 같은 부드러운 효과에 대해 관심이 없었다가 점점 CSS의 기능들에 눈을 뜨면서 스르륵 하는 효과들에 대해 관심이 생겨 이곳 저곳에 적용해보았다. 하지만 displaynone, block 으로 제어했을때 transition을 먹였음에도 불구하고 스르륵하는 시각적인 효과를 볼 수 없었다.

코드로 좀 더 확실하게 짚고 넘어가자면 일단 버튼을 클릭하면 선택된 div요소의 높이가 커지는데 스르륵하는 것을 보여주고 싶다.

예제에도 있다시피 transition을 넣었는데도 불구하고 내가 원하는 효과는 없었고 딱.딱. 끊겨 생성이 된다. 조건을 모두 마춰줬는데 왜 그럴까 대체..?

하지만 그 이유의 답은 언제나 컴퓨터는 거짓말을 하지 않는다는 것이다. 컴퓨터는 잘못이 없으니 차근차근 그 이유를 살펴보고 해결방안까지 제안하려고 한다.

📍display none, block이 될 때 무슨일이 일어나길래..?

요소가 화면에 출력되기 위해 무슨 과정을 거치는지부터 생각을 해보자. 일단 HTML과 CSS를 파싱후에 각각 DOM, CSSOM이 생성될 것이다. DOM과 CSSOM을 결합하여 렌더링 트리를 형성한다. 이 렌더링 트리는 화면에 출력될 요소들의 레이아웃을 계산하는 데 사용되고 픽셀을 화면에 렌더링하는 페인트 프로세스에 대한 입력으로 처리된다.

이때, 렌더링 트리는 화면에 출력되지 않아도 될 일부 노드(meta, script 등)와 CSS를 통해 숨겨지는 노드가 렌더링 트리에서 생략된다.

transition은 두 상태에서 속성의 변화가 일정 기간에 걸쳐 일어나도록 하지만 display: none 상태에서 동적으로 클래스를 추가하여 display: block을 추가한다고 하면 렌더 트리에 없다가 추가되는 것이기 때문에 transition의 처음 시작점이 없다. 그래서 시각적으로transition이 동작되지 않는 것처럼 보이는 것이다.

📍Transition이 먹힐 수 있는 방법

그렇다면 tranition이 되면서도 시각적으로 보였다 안보였다 할 수 있는 방법이 없을까?

없을리가...ㅎㅎ

일단 시각적인 요소만 숨기기 위함이라고 해도 2가지의 선택사항이 있는데,

  • 컨텐츠만 시각적으로 숨기지만 접근성 트리에는 있어야 하는 경우
  • 컨텐츠도 시각적으로 숨기고 접근성 트리에도 없어야 하는 경우

이 두가지의 경우로 예시를 들어보자

컨텐츠만 시각적으로 숨기지만 접근성 트리에는 있어야 하는 경우

이 경우에는 시각적으로 화면에 요소는 보이지 않지만 접근성 트리에 있어야 하고 이럴땐 diplay none block으로 처리한다면 렌더링 트리에도 없기 때문에 접근성 트리에도 구현되지 않는다. 즉, 렌더링 트리에도 있어야 하지만 요소를 시각적으로만 숨겨져야 한다.

예제를 기준으로 방법은 매우 다양하다.

  • height
/* box */
div {
  width: 100%;
  height: 0vh;
  margin-top: 10px;
  background: linear-gradient(180deg, rgba(238,174,202,1) 0%, rgba(148,187,233,1) 100%);
  transition: all 0.3s;
}
.act {
  height: 60vh;
}
  • transform
div {
  width: 100%;
  height: 60vh;
  transform: scaleY(0);
  transform-origin: 0px 0px;
  margin-top: 10px;
  background: linear-gradient(180deg, rgba(238,174,202,1) 0%, rgba(148,187,233,1) 100%);
  transition: all 0.3s;
}
.act {
  transform: scaleY(1);
}
  • opacity
div {
  width: 100%;
  height: 60vh;
  opacity: 0;
  margin-top: 10px;
  background: linear-gradient(180deg, rgba(238,174,202,1) 0%, rgba(148,187,233,1) 100%);
  transition: all 0.3s;
}
.act {
  opacity: 1;
}

컨텐츠도 시각적으로 숨기고 접근성 트리에도 없어야 하는 경우

그리고 대부분의 경우, 요소를 시각적으로 숨긴다는 것은 컨텐츠를 숨긴다는 것을 의미하는데 이는 물론 스크린리더 또한 읽히면 안된다는 것을 의미한다고 생각한다. 이렇게 구현하기 위해서는 visibility 속성을 이용하면 된다.

또는 동적으로 클래스를 붙이기 전 setTimeout을 사용하여 렌더링트리가 생성 된 후 transition을 구현할 수도 있지만 리렌더링의 문제로 visibility속성을 추천한다.

🧚‍♀️
코딩하면서 간혹 나는 잘 구현했다라고 생각했는데 생각대로 구현이 되지 않는 경우가 있다. 나의 코딩스타일이 처음엔 "앗 왜 구현 안되지?"라고 생각하면 바로 구글링해서 다른 해결방안부터 찾았는데 이제는 왜 그런지 이유를 찾아보니 매우 흥미롭고 다른 방안들의 장단점까지 알 수 있어서 매우 유익한것 같다.
다른 해결방안만 찾아서 구현하는건 코딩에 매우 안좋은 습관 같지만 일단 시간이 급하다라고 생각이 들면 구현을 우선 시 하되, 그 부분은 필기 해놓고 나중에 어떤 원리로 왜 안됐는지에 대해 찾아보는 습관을 기르도록 해야겠다.
할 일 사서 만들기..ㅎㅎ (개발자는 매우 부지런해야한다... 할 일 너므너므 많음.. 😹

📝 Reference

profile
🧚‍♀️ 사람의 시선을 잡는 프론트엔드계의 팅커벨 주니어 개발자

20개의 댓글

comment-user-thumbnail
2021년 2월 21일

와우,,, 이런 이유가 숨어있었군요. 좋은 정보 감사합니다. 스스로 고민하는 능력 배우고 갑니다.

1개의 답글
comment-user-thumbnail
2021년 2월 28일
  1. CSS animation 을 이용한다.
    fade in 일때, fade out 일때 각각 keyframe 으로 opacity 을 넣어주면 정상작동합니다.
1개의 답글
comment-user-thumbnail
2021년 5월 14일

삽질하던걸 덕분에 해결했네요...휴..

1개의 답글
comment-user-thumbnail
2021년 8월 13일

좋은 글 감사합니다

1개의 답글
comment-user-thumbnail
2021년 12월 17일

이해가 쏙쏙 되는 설명 감사합니당~~

1개의 답글
comment-user-thumbnail
2022년 2월 2일

우와 너무 좋은 팁이에요!! 공유해주셔서 감사해요😊

1개의 답글
comment-user-thumbnail
2022년 3월 2일

Really? How can start?
Use control skills to keep the wheel even happy wheels

답글 달기
comment-user-thumbnail
2022년 4월 11일

Students should check for certain terms while examining the https://cvwritingservicesuk.com as some essay reviews regularly utilize keywords such as me and I, signaling that they are aiming to generate credibility and obtain confidence. Because they want to be honest, genuine customers or users prefer nouns.

답글 달기
comment-user-thumbnail
2022년 8월 18일

꿀팁 감사합니다!
근데 div안에 textContent들이 좀 늦게 사라지는 현상이 있는데 저만 그런걸까요..?

답글 달기
comment-user-thumbnail
2022년 9월 4일

큰 도움이 되었습니다. 감사합니다.

답글 달기
comment-user-thumbnail
2023년 6월 12일

QuickBooks offers integration with Square, allowing you to sync your Square transactions and sales data directly into QuickBooks. This integration can help streamline your accounting processes and keep your financial records up to date. Here are some key points about QuickBooks integration with Square https://quickbookintegration.com/square-quickbooks-integration

답글 달기
comment-user-thumbnail
2023년 6월 29일

good exercises for 12 (kids) year olds at home. workout for 12 year olds at home
https://youtu.be/qBURRT9m9Pc

답글 달기
comment-user-thumbnail
2023년 12월 4일

For students pursuing studies in the IT field, programming is a crucial skill to master, and Java has gained significant popularity among programmers due to its concise syntax and powerful functionality. Nowadays, there is an increasing number of students taking Java courses. However, becoming proficient in Java is not an easy task. It requires students to possess strong logical thinking, grasp more complex coding structures compared to Python ghostwriting https://www.lunwenhelp.com/python-daixie/ , and learn concepts such as conditional statements, loops, branches, arrays, methods, and more.

답글 달기