이전 포스팅에서 reflow/repaint를 방지하여 CPU의 애니메이션 작업에 대한 부담을 덜어주는 내용을 기록한 적이 있다. 하지만, 프로젝트를 진행하다가 opacity
와 transform
속성만 사용하더라도 repaint 작업이 계속해서 생기는 것을 확인할 수 있었다. 위 두 속성을 사용하면 분명 reflow/repaint가 발생하지 않는다고 학습했었는데...! 찝찝한 마음이 생겨 조금 더 구글링해 본 결과, 특정 조건에 걸리면 reflow/repaint가 발생할 수 있다는 것을 알게되었다.
transform
과 opacity
만을 사용했을 때 CPU에서 애니메이션 작업 부담을 덜어줄 수 있는 것은 이미 생성된 layout에 변경 사항이 적재되는 경우이다. 이것은 다르게 얘기하면 stacking context
의 생성 조건이 충족되었다는 것이다. stacking context
생성 조건은 아래와 같다.
HTML
태그 요소position: static
, z-index: auto
가 아닌 요소opacity
가 1보다 작은 요소내가 구현한 애니메이션은 flex 컨테이너의 자식 요소였고, z-index
의 변경이 일어났다. 이것은 stacking context
생성 조건 중 두 번째에 해당하기 때문에 opacity
만 변경되는 애니메이션임에도 불구하고 repaint 작업이 아래와 같이 발생하는 것을 확인할 수 있었다(크롬 개발자도구 performance 탭).
그렇다면 stacking context란 무엇일까?
요소들은 stacking context의 특성에 따라 가상의 z축에 쌓이면서 순서대로 렌더링되는 모습으로 그려진다. 그리고 이 순서는 CSS의 z-index
값으로 부여할 수 있지만, 이 값은 해당 요소의 부모 요소에게만 의미가 있다. z-index
값이 음수가 아닌 이상, 자식 요소는 부모 요소 위에 그려진다(자식 요소의 z-index
값이 부모 요소의 z-index
값보다 작다고 할지라도).
요소들이 렌더링되는 순서 (쌓임 순서)는 아래와 같다.
HTML
요소position
값이 존재하고 음수의 z-index
값을 가지는 요소position
값이 존재하지 않는 요소 (position: static
)position
값이 존재하고 z-index: auto
또는 z-index: 0
인 요소position
값이 존재하고 양수의 z-index
값을 가지는 요소아래는 MDN 문서에서 예시로 사용된 이미지이다. z-index
값만 따진다면 Div#4 요소가 Div#1 요소 위에 렌더링되어야 하는데, 쌓임 순서에 따라 Div#3 요소의 자식 요소인 Div#4는 Div#1 요소 위에 올 수 없는 모습이다. 즉, Div#3의 자식 요소들은 z-index
가 5 이상인 다른 요소 위에 렌더링될 수 없으며, Div#3의 자식 요소들끼리만 z-index
를 비교하게 되는 것이다.
[MDN] 쌓임 맥락
[CSS] opacity는 reflow가 발생 안 한다구요...? 정말??
TIL no.10 - CSS - 쌓임 맥락(stacking context)