[CSS] Stacking context

위 링크 페이지를 옮긴 글 입니다.
[문제]
3개의 div 에 span 으로 각각 bg color 를 적용하였고, position 은 absolute 입니다. red 는 z-index가 1입니다. 나머지는 없습니다. 여기서 아래 조건을 지키면서 red를 green 과 blue 뒤로 보내보세요.
- HTML markup 을 바꾸지 마세요.
- z-index를 추가하거나 바꾸지 마세요.
- position 요소를 추가하거나 바꾸지 마세요.
[답]
red의 div에 opacity 를 1보다 작은 값(e.g. 0.99)으로 적용하면 됩니다.
Stacking Order
z-index 는 아주 간단해 보입니다. 높은 z-index를 가지고 있는 element 는 낮은 것보다 앞에 노출 됩니다. 맞나요? 사실 아닙니다.이는 z-index와 관련된 문제 중 일부입니다. 이는 아주 간단해 보입니다. 그래서 많은 개발자들이 이와 관련된 rule에 대해서 읽는데 많은 시간을 들이지 않습니다.
html document의 모든 elements는 document내에서 다른 element 보다 앞에 있거나 뒤에 있을 수 있습니다. 이것이 stacking order라고 알려져 있습니다. 이 순서를 결정하는 규칙은 스펙에 명확하게 정의되어 있습니다. 하지만 언급했듯이, 대부분의 개발자들이 완전히 이해하지 못하고 있습니다.
z-index와 position 요소들이 포함되어 있지 않으면, 규칙은 아주 간단합니다. 기본적으로 stacking order 는 html의 노출 순서와 같습니다. ( 맞아요. 사실 그것보다는 좀 더 복잡하긴 합니다. inline element에 겹쳐지도록 nagetive margin 을 사용하지 않는 한, 예외 상황이 발생하진 않을것입니다.)
position 요소를 섞어서 소개할 때, 몇몇 position 을 갖고 있는 요소는 그것을 가지고 있지 않는 요소보다 앞에서 노출 됩니다. (e.g. relative, absolute)
z-index를 포함하게 되면, 상황이 좀 달라집니다. 먼저 z-index 가 높은 요소가 낮은 요소보다, 그리고 z-index 가 있는 요소는 없는 요소보다 앞에서 노출될것이라고 자연스럽게 추측하게 됩니다. 그러나 그렇게 간단하지는 않습니다. 무엇보다도 z-index는 position 을 갖고 있는 element 위에서 작동합니다. 만약에 position 을 갖고 있지않는 element 에 z-index를 적용하려고 한다면 작동하지 않을 것입니다. 그 다음으로는 z-index 값은 stacking context를 만듭니다. 그리고 이제 단순해 보였던 것이 더 복잡해집니다.
Stacking Contexts
스택 순서에서 앞뒤로 함께 이동하는 공통 부모가 있는 element 그룹은 stacking context를 만듭니다. stacking context 에 대해서 완전히 이해하는 것은 z-index와 stacking order 작동을 이해하는데 필요합니다.
모든 stacking context 는 single HTML element 를 root element로 가지고 있습니다. element 에서 새로운 stacking context가 만들어 질 때, stacking context는 모든 child elements 를 stacking order에 의해 특정 위치로 제한합니다. 이는 특정 element가 stacking order에서 바닥에 위치하고 있는 stacking context 에 포함되어 있다면, stacking order에서 더 높은 위치에 있는 다른 stacking context보다 앞에 노출 될 수 있는 방법은 없습니다. 아무리 높은 z-index 값을 갖는다하더라도..
새로운 stacking context 는 다음 세가지 방법 중 하나로 element 에 생성 됩니다
- element가 document 의 root element 일 때
- element 가 static 이 아닌 다른 position 값을 가지고, z-index 값이 auto 가 아닐 때
- element 가 1보다 작은 opacity 값을 가질 때
stacking context 를 만드는 첫번째, 두번째 방법은 이해하기도 쉽고 일반적으로 많은 웹 개발자들이 이해하고 있습니다. (그것을 무엇이라 부르는지 모르더라도..)
세번째 방법은 w3c 스펙 문서외에서는 거의 언급이 되지 않고 있습니다.
Update: opacity 에 대해서 추가하자면, 새로운 몇몇 CSS 요소들도 stacking context 를 만듭니다. transfoms, filters, css-regions, paged media 등등. 기본적인 규칙에서는 css 속성에서 offscreen context로 렌더링해야 한다면, 새로운 stacking context 를 만들어야 합니다.
Stacking Order 안에서 Element의 위치 결정
실제로 페이지(border, background, text node 포함)안에서 모든 element들의 global stacking order 를 결정하는 것은 복잡합니다. 그리고 이 글의 범위를 넘어갑니다.(이 스펙 보시길 권하시네요. the spec => updated spec).
그러나 대부분의 계획, 목적을 달성하기 위해 순서에 대한 기본적 이해는 장기적으로 갈 수 있게 하고 css 개발에 대한 안목을 가지는데 도움이 됩니다. 자 이제 순서를 개별적인 stacking context로 분류하는 것부터 시작하겠습니다.
같은 Stacking Context 에서의 Stacking Order
단독 stacking context (뒤에서 앞으로) 안에서 stacking order를 결정하는 기본적인 규칙이 있습니다.
- stacking context의 root element
- z-index를 음수값으로 갖는 positioned element (children 포함)
(높은 값은 낮은 값보다 앞에 쌓입니다. 같은 값은 HTML의 모양에 따라 쌓입니다.) - Non-positioned (HTML의 모양에 의한 순서)
auto
를 z-index 값으로 갖는 Positioned elements (children 포함)
(HTML의 모양에 의한 순서)- 양수의 값을 z-index값으로 갖는 Positioned elements(children 포함)
(높은 값은 낮은 값보다 앞에 쌓입니다. 같은 값은 HTML의 모양에 따라 쌓입니다.)
Note: 음수의 z-index 값을 갖는 Positioned element들은 stacking context 안에서 첫번째의 순서를 갖습니다. 이는 모든 요소들 뒤에 위치하여 보여진다는 것입니다. 이유는 다음과 같습니다. 어떤 element가 그 부모 element뒤에 위치하여 노출되는 것이 가능해집니다. 이는 일반적으로는 불가능합니다. 이는 부모 element가 같은 stacking context 안에 있을 때만 유효하고, stacking context 의 root element 가 아니어야 합니다. 가장 좋은 예제는 Nicolas Gallagher’s CSS drop-shadows without images 입니다.
Global Stacking Order
새로운 stacking context 들이 어떻게/언제 만들어지는지와 stacking context 안에서 stacking order에 대해서 이해하고 나서, 특정 element가 global stacking order 안에서 어디에 노출 될 것인지를 파악하는 것은 나쁘지 않습니다.
잘못을 막는 방법은 새로운 stacking context 가 형성 되었을 때, 발견 할 수 있어야 한다는 것입니다. 만약 당신이 10억의 z-index 값을 주었는데 stacking order 내에서 앞으로 이동하지 않는 다면, 트리 구조내에서 조상을 살펴보고 어떤 상위 요소가 stacking context를 형성한건 아닌지 봐야 합니다. 실제로 그런일이 발생 했다면, 당신의 10억 z-index 값은 아무런 도움이 되지 않을 것입니다.
도움의 글