z-Index와 Stacking contexts

Yiseul·2022년 1월 14일
0

조각지식

목록 보기
12/20

기본적으로 z-index는 레이어 순서를 말한다. 포토샵을 생각하면 되는데 바탕이 되는 레이어가 있으면 그 위에 구성 요소들이 쌓이는 식이다.
z-index의 수가 클수록 위로 올라온다. 하지만 단순히 z-index의 값이 큰 것으로만 제어되지 않는 경우가 꽤 있다는 것!

<style>
  header {
    position: relative;
    z-index: 2;
  }
  .tooltip {
    position: absolute;
    z-index: 999999;
  }
  main {
    position: relative;
    z-index: 1;
  }
</style>

<header>
  My Cool Site
</header>
<main>
  <div class="tooltip">
    A tooltip
  </div>
  <p>Some main content</p>
</main>

위와 같은 코드가 있을 때 가장 위로 올라오는 것은 무엇일까?
단순히 생각하면 999999에 독립적인 포지션을 가지는 툴팁이 가장 위로 올라온다고 생각할 수 있겠지만 헤더에 의해 덮혀진다.

The root context

  • header
  • main
    -- tool tip

stacking contexts

포토샵의 레이아웃을 묶어서 한 그룹을 짓듯 우리는 요소들을 <div></div> 같은 태그로 묶어 나간다. 하나의 쌓임 맥락은 부모 쌓임 맥락 안에서 통째로 하나의 단위로 간주됩니다. -mdn 요소에 z-index 지정하면 해당 값은 동일한 컨텍스트의 요소와 비교된다. z-index 값은 전역이 아니다.

이런 컨텍스트를 만드는 일반적인 방법은 다음과 같다.

.some-element {
  position: relative;
  z-index: 1;
}

그럼 위의 예제를 툴팁이 올라오게 하는 방법은 어떻게 될까?
사실 main은 스택 컨텍스트를 생성할 필요가 없다.

<style>
  header {
    position: relative;
    z-index: 2;
  }
  .tooltip {
    position: absolute;
    z-index: 999999;
  }
  main {
    position: relative;
    /* No more z-index here! */
  }
</style>

<header>
  My Cool Site
</header>
<main>
  <div class="tooltip">
    A tooltip
  </div>
  <p>Some main content</p>
</main>

Z-index가 없으면 main은 스태킹 컨텍스트를 생성하지 않기 때문에 계층 구조가 달라진다.

The root context

  • header
  • tool tip

헤더와 툴팁이 이제 동일한 컨텍스트에 있기 때문에 z-인덱스 값을 비교해서 값이 더 큰 툴팁이 위로 올라오게 된다.

여기서 부모/자식 관계에 대해 이야기하는 것이 아닙니다. 툴팁이 헤더보다 더 깊게 중첩되어도 상관 없습니다. 브라우저는 스택 컨텍스트에만 관심이 있습니다. - josh

그런데 만약 main에 z-index값을 사용해야 하거나 스택 컨텍스트를 생성해야하는 상황이라면?

CSS의 규칙에 따르면 쌓이는 컨텍스트를 "해제"할 수 있는 방법은 없다. 한 스택 컨텍스트 내의 요소는 다른 스택 컨텍스트의 요소와 비교할 수 없다.

툴팁값을 <body> 에 부여하고 CSS를 사용해서 적절하게 배치하여 해당 요소의 자식인 것처럼 보이게 할 수 있다 - 고 하는데 이것은 고급 기술이며 키보드를 사용하여 탐색하는 사용자의 경험을 실수로 중단하지 않도록 세심한 계획이 필요합니다 라고 덧붙여있다.😅

z-index, 포지션값 외에
stacking contexts가 생성되는 경우

  • 1보다 작은 opacity값 세팅
  • fixed나 sticky로 포지셔닝
  • normal이 아닌 mix-blend-mode값 적용
  • display:flex or display:grid로 지정한 컨테이너 안에 자식요소에 z-index값을 지정한 경우
  • transform, filter, clip-path, or perspective 사용하는 경우
  • opacity or transform 같은 값에 will-change를 함께 적용하는 경우
  • isolation: isolate로 명시적으로 컨텍스트를 만드는 경우
    etc...

z-index가 작동하려면 position과 같이 설정해야 합니다. 맞나요?

일반적으로 z-index는 포지셔닝이 설정된 값에서만 작동한다.
그러나 flex에서는 포지션이 기본값(static)인 경우에도 작동한다.

생각해 볼 문제?

z-색인을 사용하는 것은 일반적으로 상위 스택 컨텍스트에서
다른 요소의 위/아래로 해당 요소를 올리거나 내릴 때이다.

스태킹 컨텍스트가 생성되면 모든 하위 항목을 "평면화"하고 미묘하게 진단하기 어려운 버그를 유발할 수 있다. 하지만 모든 걸 전역적으로 비교하는 것이 과연 좋은 방법이 될까?

isolation

.wrapper {
  isolation: isolate;
}

isolation은 가능한 가장 순수한 방법으로 스택 컨텍스트를 생성한다.

  • z-index 값이 필요하지 않다.
  • position 기본값(static)에서 사용할 수 있다.
  • 자식요소의 렌더링에 영향을 미치지 않는다.

브라우저 지원도 우수해서 IE를 고려해야 하는 경우
transform: translate(0px); 대신 사용하는 것도 좋을 것이라고 하는데 트랜스폼 속성 쓰면 써봐야겠다.

맨날 트랜스폼 뭐였더라 하면서 트랜지션 트랜스레이트 트랜스폼 헷갈리는 사람... ✋🏻 저요...



https://www.joshwcomeau.com/css/stacking-contexts/
넓고도 깊은 css의 세계 😶‍🌫️

profile
즐거운 도전중입니다:)

0개의 댓글