그 Transform을 넣은 요소의 자식에 fixed를 넣지말라.

Posted by in Research

두어달 전에 상품광고_CCP(그림 1) 관련 작업을 진행하며 발견한 이슈다.

img_ccp
그림1. 상품광고_CCP 화면

상품광고_CCP 구현 스펙 중에 플리킹에 대한 구현 이슈가 있었는데,
개발조직에서 jindo를 사용하기로 결론이 나왔고, 그에 맞춰서 마크업 구조도 일관성있게 맞춰서 공유하였다.
사실 jindo만큼 한국에서 쓰기 편한 라이브러리도 없는 거 같기는 하다. 물론 상황에 맞게 쓰는게 최고지만.

어쨌든 여기서 simple형 헤더라는 걸 제공했는데,
이 simple형 헤더라는 녀석은 스크롤의 위치가 어디던간에 상단에 고정(position:fixed)이었다.

img_ccp2
그림 2. 심플형 헤더

대충 상황은 알거라 생각한다.
당시 스펙의 마크업은 이러했다. (코드 자체를 긁어온게 아니니 대충 어떤 느낌인지만 보시라)

위의 코드에 진도 플리킹을 넣으면 코드가 아래처럼 바뀐다.

여기서 header에 클래스를 넣게 되면,
position:fixed가 들어가면서 자연스럽게 상단에 고정하는데,
이상하게 플리킹 코드만 넣으면 에러가 나더라.(!)

처음에는 버그인 줄 알고 막 이것저것 찾아봤는데,
jindo를 비롯한 대부분의 플리킹 라이브러리에서 유용하게 사용하고 있는, transform 속성이 문제였다.

W3C의 transform 명세에서 fixed를 검색해보면,
transform rendering model이라는 섹션 내부의 NOTE에 영어로 된 문구가 써져있다.
어쨌든 이게 문제인 거 같으니 이 부분의 첫문장을 봤더니,

Specifying a value other than none for the transform property establishes a new local coordinate system at the element that it is applied to
transform 속성의 값으로 none 의외의 것을 넣으면 새로운 지역 좌표 시스템을 생성한다.

라고 되어있다.

여기서 주목해야하는 건, local coordinate system이다.
local coordniate system이란 HTML 요소에 Position 관련 CSS를 넣었을 때,
그 Position의 기준이 되는 시스템 체계를 나타낸다.

예를 들어 웹 브라우저의 기본 local coordinate system은 document 내부의 canvas 영역 그 자체이다.

[렌더링 확인]

position:fixed를 넣고 좌상단에 포지션을 지정하면 해당 위치에 고정하는 모습을 확인할 수 있다.
(스크롤을 돌려보시라)

그러나 부모 요소에 trasform속성을 추가하면 이 코드는 내가 원하는 모습을 보이지 않는다.

[렌더링 확인]

이는 모든 브라우저에서 동일하게 발생하는 현상이고,
버그가 아니기 때문에 브라우저의 동작 변경을 기대하기는 어렵다.
왜 이따구로 만들었나

결론

당시에는 이 문제를 결국 position : absolute로 넣고,
스크립트에서 top좌표를 일일히 계산해서 넣는 방법으로 해결했었다.

이후에는 스펙을 변경하여,
상단의 header부분을 아예 플리킹 영역 밖으로 빼서 관리하는 방식으로 가기로 하여,
CCP 작업 때는 position : fixed를 잘 활용했지만, 만약 다른 작업에서 동일한 UI를 제작해야 한다면,
되도록이면 fixed사용을 지양하는 것이 좋겠다.

오랜만에 이상한 스펙을 만난 거 같다.