해당 게시물은 https://css-for-js.dev/ 코스를 학습하며 정리한 내용입니다.
사전 지식 : 쌓임 맥락
z-index는 특정 조건에서만 효력이 발생한다.
특히 브라우저의 기본 레이아웃인 Flow Layout 모드에선 효력이 없다.
https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
Z-index가 관리하기 어려운 이유
내가 언제 어디서 어떤 숫자를 썼더라...?
일반적인 방법 : 높은 Z-index 주기
일반적으로 위와 같이 이미지 위에 카드를 올리고 싶으면, z-index를 주면 된다.
z-index는 z축이다. 클수록 위로 튀어나온다.
<style>
.wrapper {
/* Create a containing block */
position: relative;
}
.card {
position: relative;
z-index: 2;
}
.decoration {
position: absolute;
z-index: 1;
}
</style>
<div class="wrapper">
<div class="card">
Hello World
</div>
<img
alt=""
src="/decorative-blob-1.svg"
class="decoration"
style="top: -20px; left: -70px;"
/>
<img
alt=""
src="/decorative-blob-2.svg"
class="decoration"
style="top: -50px; left: -10px;"
/>
<!-- Other blobs omitted for brevity -->
</div>
Relative Layout Mode 요소들은 순서대로 쌓인다.
참고 : 브라우저의 렌더링 순서
- 먼저 위치가 지정되지 않은 모든 요소가 렌더링됩니다(Flow, Flexbox, Grid...).
- 다음으로, 위치 지정 요소가 맨 위에 렌더링됩니다 (relative, absolute, fixed, sticky).
- 브라우저는 각 단계마다 뒤에 나오는 요소를 위에 올립니다.
아래 사항을 고려하면 z-index를 없앨 수 있다.
- wrapper에는 position:relative를 적용한다.(즉 Relative Layout 모드를 따른다)
- relative layout 요소끼리 나오는 순서대로 쌓인다.
- .decoration 클래스 적용 요소는 .wrapper 기준으로 위치한다.
즉, 아래와 같이 바꿀 수 있다.
<style>
.wrapper {
position: relative;
}
.card {
position: relative;
}
.decoration {
position: absolute;
}
</style>
<div class="wrapper">
<img
alt=""
src="/course-materials/decorative-blob-1.svg"
class="decoration"
style="top: -20px; left: -70px;"
/>
<img
alt=""
src="/course-materials/decorative-blob-2.svg"
class="decoration"
style="top: -50px; left: -10px;"
/>
<img
alt=""
src="/course-materials/decorative-blob-3.svg"
class="decoration"
style="bottom: -80px; right: -50px;"
/>
<img
alt=""
src="/course-materials/decorative-blob-4.svg"
class="decoration"
style="bottom: 50px; right: -120px;"
/>
<div class="card">
Hello World
</div>
</div>
주의 : Link, Button ,Form, Input 같은 대화형 요소는 돔 순서를 바꾸면 탭 순서가 바뀐다.
쌓임 맥락 격리
아래와 같은 화면이 있었다.
z-index를 써서 아래와 같이 바꿨다.
<style>
.card {
position: relative;
z-index: 1;
}
.primary.card {
z-index: 2;
}
</style>
<section class="pricing">
<article class="card">
<!-- Stuff omitted -->
</article>
<article class="primary card">
<!-- Stuff omitted -->
</article>
<article class="card">
<!-- Stuff omitted -->
</article>
</section>
아뿔사! header의 z-index가 2였다.
<style>
header {
position: fixed;
z-index: 2;
}
.card {
position: relative;
z-index: 1;
}
.primary.card {
z-index: 2;
}
</style>
<header>Synergistic Inc.</header>
<main>
<section class="pricing">
<article class="card">
<!-- Stuff omitted -->
</article>
<article class="primary card">
<!-- Stuff omitted -->
</article>
<article class="card">
<!-- Stuff omitted -->
</article>
</section>
</main>
해당 현상의 원인은 다음과 같다.
1 : header, .card, .primary.card의 쌓임 맥락은 동일 레벨이다. (:root 아래)
2 : header보다 .primar.card가 뒤에 나오므로 위에 쌓인다.
이 문제는, 새로운 쌓임 맥락을 만들어 해결할 수 있다.
계층화된 요소를 쌓임맥락으로 묶어(격리해) z-인덱스 값이 있는 "최상위" 요소의 수를 줄인다.
.pricing {
position: relative;
z-index: 1;
}
비유하자면 2 vs 1.2 이렇게 비교하는 효과가 생긴다.
1.2전체 위에 2가 쌓이게 되는 것이다.
isolation property
주의! : 해당 방법은 IE에서 못씀
z-index의 문제는, 최상위 z-index 사용 요소들 간의 경합이다.
이는 컴포넌트 기반 개발을 하게 되면 더 큰 문제가 된다.
isolation property를 이용하면 z-index없이 쌓임 맥락을 만들 수 있다.
.pricing {
isolation: isolate;
}
이는 해당 요소가 독립적인 쌓임 맥락을 갖는다는 것을 의미한다.
예제 코드 보기
https://codesandbox.io/s/hardcore-fog-7vex5?file=/index.html
더 많은 자료 보기
'FrontEnd' 카테고리의 다른 글
[React][Remix][tutorial]React-Remix를 이용하여 개발자 블로그 만들기. (0) | 2022.01.27 |
---|---|
[React][CSS] css를 styled-component로 변환하기 (0) | 2022.01.18 |
[CSS][Layout][Positioned Layout][Stacking Contexts : 쌓임 맥락] (0) | 2022.01.16 |
[CSS][Layout][Positioned Layout][Absolute Positioning] (0) | 2022.01.16 |
[CSS][Layout][Positioned Layout][Relative Positioning] (0) | 2022.01.16 |