CSS의 요소에 z-index: 99999를 설정했는데 다른 요소 위에 표시되지 않은 적이 있나요? 모든 다른 요소가 더 낮은 값으로 설정되거나 전혀 설정되지 않는다고 가정할 때 값이 크면 해당 요소가 시각적으로 다른 요소 위에 쉽게 배치됩니다. 웹페이지는 일반적으로 2차원 공간으로 표현됩니다. 그러나 특정 CSS 속성을 적용하면 가상의 z축 평면이 도입되어 깊이를 전달합니다. 이 평면은 화면에 수직이며 사용자는 이 평면에서 요소의 순서를 인식합니다. 누적된 요소에 대한 사용자의 인식인 가상의 z축 뒤에 있는 아이디어는 이를 생성하는 CSS 속성이 결합되어 누적 컨텍스트라고 부르는 것을 형성한다는 것입니다. 웹페이지에서 요소가 "스택"되는 방식, 스택 순서를 제어하는 방법, 필요할 때 요소를 "스택 해제"하는 실용적인 접근 방식에 대해 이야기하겠습니다. 스택 컨텍스트 정보 웹페이지를 책상이라고 상상해 보세요. HTML 요소를 추가하면 책상 위에 종이 조각이 하나씩 놓여지게 됩니다. 배치된 마지막 종이는 가장 최근에 추가된 HTML 요소와 동일하며 그 앞에 배치된 다른 모든 문서 위에 위치합니다. 이는 중첩된 요소의 경우에도 일반적인 문서 흐름입니다. 데스크 자체는 다른 모든 폴더를 포함하는 요소로 구성된 루트 스태킹 컨텍스트를 나타냅니다. 이제 특정 CSS 속성이 작동합니다. 위치(z-인덱스 포함), 불투명도, 변환 및 포함과 같은 속성은 폴더처럼 작동합니다. 이 폴더는 요소와 모든 하위 요소를 가져와서 기본 스택에서 추출한 다음 별도의 하위 스택으로 그룹화하여 스택 컨텍스트라고 부르는 것을 만듭니다. 위치가 지정된 요소의 경우 auto가 아닌 z-index 값을 선언하면 이런 일이 발생합니다. 불투명도, 변환 및 필터와 같은 속성의 경우 특정 값이 적용될 때 스택 컨텍스트가 자동으로 생성됩니다.
이것을 이해하십시오: 일단 종이 조각(즉, 하위 요소)이 폴더(즉, 상위의 스태킹 컨텍스트) 안에 있으면 결코 해당 폴더를 나갈 수 없거나 다른 폴더의 종이 사이에 배치될 수 없습니다. 해당 Z-색인은 이제 자체 폴더 내에서만 관련됩니다.
아래 그림에서 용지 B는 이제 폴더 B의 스택 컨텍스트 내에 있으며 폴더의 다른 용지와 함께만 주문할 수 있습니다.
책상 위에 두 개의 폴더가 있다고 상상해 보세요.
.folder-a { z-색인: 1; } .folder-b { z-색인: 2; }
마크업을 조금 업데이트해 보겠습니다. 내부 폴더 A는 Z-색인: 9999인 특수 페이지입니다. 내부 폴더 B는 일반 페이지인 Z-색인: 5입니다.
.special-page { z-색인: 9999; } .plain-page { z-색인: 5; }
어느 페이지가 맨 위에 있나요? 폴더 B의 .plain-page입니다. 브라우저는 하위 문서를 무시하고 두 폴더를 먼저 쌓습니다. 폴더 B(z-index: 2)를 보고 폴더 A(z-index: 1) 위에 배치합니다. 왜냐하면 2가 1보다 크다는 것을 알기 때문입니다. 한편, z-index: 9999 페이지로 설정된 .special-page는 z-index가 가능한 가장 높은 값으로 설정되어 있어도 스택 맨 아래에 있습니다. 스태킹 컨텍스트는 중첩되어(폴더 내의 폴더) "가계도"를 생성할 수도 있습니다. 동일한 원칙이 적용됩니다. 즉, 자식은 부모 폴더에서 벗어날 수 없습니다. 이제 스태킹 컨텍스트가 레이어를 그룹화하고 순서를 변경하는 폴더처럼 작동하는 방식을 알았으므로 다음과 같이 질문해 볼 가치가 있습니다. 변환 및 불투명도와 같은 특정 속성이 왜 새로운 스태킹 컨텍스트를 생성합니까? 문제는 다음과 같습니다. 이러한 속성은 모양 때문에 스택 컨텍스트를 생성하지 않습니다. 그들은 브라우저가 내부적으로 작동하는 방식 때문에 그렇게 합니다. 변환, 불투명도, 필터 또는 원근감을 적용하면 브라우저에 "이 요소는 이동, 회전 또는 희미해질 수 있으므로 준비하세요!"라고 말하는 것입니다.
이러한 속성을 사용하면 브라우저는 렌더링을 보다 효율적으로 관리하기 위해 새로운 스택 컨텍스트를 생성합니다. 이를 통해 브라우저는 애니메이션, 변형 및 시각 효과를 독립적으로 처리할 수 있으므로 이러한 요소가 페이지의 나머지 부분과 상호 작용하는 방식을 다시 계산할 필요성이 줄어듭니다. 브라우저가 "이 폴더를 별도로 처리해 그 안의 내용이 변경될 때마다 전체 책상을 뒤섞을 필요가 없습니다."라고 말하는 것과 같다고 생각하세요. 하지만 거기에는부작용. 브라우저가 요소를 자체 레이어로 들어 올리고 나면 그 안에 있는 모든 것을 "평면화"하여 새로운 스택 컨텍스트를 생성해야 합니다. 이는 책상에서 폴더를 꺼내 별도로 처리하는 것과 같습니다. 해당 폴더 안의 모든 항목은 그룹화되며 브라우저는 이제 무엇 위에 놓일지 결정할 때 이를 단일 단위로 처리합니다. 따라서 변형 및 불투명도 속성이 요소가 시각적으로 쌓이는 방식에 영향을 주지 않는 것처럼 보일 수도 있지만 이는 성능 최적화를 위한 것입니다. 다른 여러 CSS 속성도 비슷한 이유로 스택 컨텍스트를 생성할 수 있습니다. 더 자세히 알아보고 싶다면 MDN이 전체 목록을 제공합니다. 꽤 많은 것들이 있는데, 이는 알지 못한 채 스택 컨텍스트를 실수로 생성하는 것이 얼마나 쉬운지를 보여주는 것뿐입니다. "언스태킹" 문제 스태킹 문제는 여러 가지 이유로 발생할 수 있지만 일부는 다른 것보다 더 일반적입니다. 모달 구성 요소는 다른 모든 요소 위에 있는 최상위 레이어에서 구성 요소를 "열기" 위해 토글한 다음 "닫힐" 때 최상위 레이어에서 제거해야 하기 때문에 고전적인 패턴입니다. 나는 우리 모두가 모달을 열었지만 어떤 이유로든 나타나지 않는 상황에 직면했다고 확신합니다. 제대로 열리지 않은 것이 아니라 스태킹 컨텍스트의 하위 레이어에서 보이지 않는 것입니다. 이로 인해 "왜?"라는 의문이 생깁니다. 설정한 이후:
.오버레이 { 위치: 고정; /* 스태킹 컨텍스트 생성 */ Z-색인: 1; /* 요소를 다른 모든 것 위에 있는 레이어에 배치합니다 */ 삽입: 0; 너비: 100%; 높이: 100vh; 오버플로: 숨김; 배경색: #00000080; }
이는 정확해 보이지만 모달 트리거를 포함하는 상위 요소가 z-index: 1로 설정된 다른 상위 요소 내의 하위 요소인 경우 기술적으로 기본 폴더에 의해 가려진 하위 레이어에 모달을 배치합니다. 특정 시나리오와 몇 가지 일반적인 스태킹 컨텍스트 함정을 살펴보겠습니다. 실수로 스택 컨텍스트를 생성하는 것이 얼마나 쉬운지뿐만 아니라 이를 잘못 관리하는 방법도 알게 될 것입니다. 또한 관리 상태로 돌아가는 방법은 상황에 따라 다릅니다. 시나리오 1: 갇힌 모달
낮은 레벨 레이어에 갇혀 있는 모달을 즉시 확인하고 상위 레이어를 식별할 수 있습니다. 브라우저 확장 현명한 개발자들은 도움을 주기 위해 확장 기능을 구축했습니다. "CSS Stacking Context Inspector" Chrome 확장 프로그램과 같은 도구는 DevTools에 추가 z-index 탭을 추가하여 스태킹 컨텍스트를 생성하는 요소에 대한 정보를 표시합니다.
IDE 확장 잠재적인 스택 컨텍스트 문제를 편집기에서 직접 강조 표시하는 VS Code용 확장 기능을 사용하면 개발 중에 문제를 발견할 수도 있습니다.
언스태킹 및 제어권 회복 근본 원인을 파악한 후 다음 단계는 이를 처리하는 것입니다. 이 문제를 해결하기 위해 취할 수 있는 몇 가지 접근 방식이 있으며 순서대로 나열하겠습니다. 하지만 어떤 수준에서든 누구든 선택할 수 있습니다. 누구도 다른 사람을 불평하거나 방해할 수 없습니다. HTML 구조 변경 이는 최적의 수정으로 간주됩니다. 스택 컨텍스트 문제가 발생하려면 HTML 내에서 일부 요소를 이상한 위치에 배치해야 합니다. 페이지를 재구성하면 DOM의 모양을 바꾸고 스택 컨텍스트 문제를 제거하는 데 도움이 됩니다. 문제가 있는 요소를 찾아 HTML 마크업의 트랩 요소에서 제거합니다. 예를 들어, .modal-container를 헤더 밖으로 이동하고
요소에 단독으로 배치하여 첫 번째 시나리오인 "The Trapped Modal"을 해결할 수 있습니다.<헤더 클래스="헤더">
헤더
<메인 클래스="콘텐츠">주요 내용
이 콘텐츠의 Z-색인은 2이며 여전히 모달을 포함하지 않습니다.
모달 제목
이제 저는 아무것도 배후에 있지 않습니다. DOM 구조 조정으로 인해 더 나은 위치를 확보하게 되었습니다.
"모달 열기" 버튼을 클릭하면 모달이 예상대로 다른 모든 것 앞에 배치됩니다. Shoyombo Gabriel Ayomide의 펜 시나리오 1: 갇힌 모달(솔루션) [포크]를 참조하세요. 조정CSS의 상위 스태킹 컨텍스트 요소가 레이아웃을 깨지 않고는 이동할 수 없는 요소라면 어떻게 될까요? 문제를 해결하는 것이 더 좋습니다. 부모가 컨텍스트를 설정합니다. 컨텍스트를 트리거하는 CSS 속성(또는 속성)을 찾아 제거합니다. 목적이 있고 제거할 수 없는 경우 상위 요소에 형제 요소보다 높은 z-index 값을 지정하여 전체 컨테이너를 들어올립니다. Z-색인 값이 높을수록 상위 컨테이너가 맨 위로 이동하고 해당 하위 컨테이너가 사용자에게 더 가까이 표시됩니다. "The Submerged Dropdown" 시나리오에서 배운 내용에 따르면 드롭다운을 탐색 모음 밖으로 이동할 수 없습니다. 그것은 말이 되지 않습니다. 그러나 .navbar 컨테이너의 z-index 값을 .content 요소의 z-index 값보다 크게 늘릴 수 있습니다. .navbar { 배경: #333; /* z-인덱스: 1; */ Z-인덱스: 3; 위치: 상대; }
이번 변경으로 이제 .dropdown-menu가 문제 없이 콘텐츠 앞에 표시됩니다. Shoyombo Gabriel Ayomide의 펜 시나리오 2: 물속에 잠긴 드롭다운(솔루션) [포크됨]을 참조하세요. 프레임워크를 사용하는 경우 포털을 사용해 보세요. React 또는 Vue와 같은 프레임워크에서 Portal은 DOM의 일반적인 상위 계층 구조 외부에 구성 요소를 렌더링할 수 있는 기능입니다. 포털은 구성 요소의 순간 이동 장치와 같습니다. 이를 사용하면 문서의 어느 위치에서든(일반적으로 document.body에 바로) 구성 요소의 HTML을 렌더링할 수 있으며 소품, 상태 및 이벤트에 대한 원래 상위 항목에 논리적으로 연결된 상태를 유지할 수 있습니다. 렌더링된 출력이 말 그대로 문제가 있는 상위 컨테이너 외부에 나타나기 때문에 이는 스택 컨텍스트 트랩을 탈출하는 데 적합합니다. ReactDOM.createPortal( <툴팁 />, 문서.본문 );
이렇게 하면 상위 항목에 Overflow: Hidden 또는 낮은 Z-색인이 있더라도 드롭다운 콘텐츠가 상위 항목 뒤에 숨겨지지 않습니다. 이전에 살펴본 "클립된 도구 설명" 시나리오에서는 포털을 사용하여 도구 설명을 오버플로로부터 구출했습니다. 숨겨진 클립을 문서 본문에 배치하고 컨테이너 내 트리거 위에 배치했습니다. 펜 시나리오 3: 잘린 도구 설명(솔루션) [포크됨](Shoyombo Gabriel Ayomide 작성)을 참조하세요. 부작용 없는 스태킹 컨텍스트 소개 이전 섹션에서 설명된 모든 접근 방식은 문제가 있는 스택 컨텍스트에서 요소를 "언스택"하는 것을 목표로 하지만 실제로 스택 컨텍스트를 생성해야 하거나 생성하려는 몇 가지 상황이 있습니다. 새로운 스태킹 컨텍스트를 만드는 것은 쉽지만 모든 접근 방식에는 부작용이 있습니다. 즉, 격리 사용을 제외하고: 격리합니다. 요소에 적용될 때 해당 요소 자식의 스택 컨텍스트는 외부 요소의 영향을 받는 것이 아니라 각 자식을 기준으로 해당 컨텍스트 내에서 결정됩니다. 전형적인 예는 해당 요소에 z-index: -1과 같은 음수 값을 할당하는 것입니다. .card 구성요소가 있다고 상상해 보세요. .card의 텍스트 뒤에 있지만 카드 배경 위에 장식 모양을 추가하려고 합니다. 카드에 스태킹 컨텍스트가 없으면 z-index: -1은 모양을 루트 스태킹 컨텍스트(전체 페이지)의 맨 아래로 보냅니다. 이렇게 하면 .card의 흰색 배경 뒤로 사라집니다. Shoyombo Gabriel Ayomide의 Pen Negative z-index(문제) [forked]를 참조하세요. 이 문제를 해결하기 위해 상위 .card에 격리: 격리를 선언합니다. Shoyombo Gabriel Ayomide의 Pen Negative z-index(솔루션) [forked]를 참조하세요. 이제 .card 요소 자체가 스태킹 컨텍스트가 됩니다. 자식 요소( :before 의사 요소에 생성된 장식 모양)의 z-index: -1이 있으면 상위 스택 컨텍스트의 맨 아래로 이동합니다. 의도한 대로 텍스트 뒤와 카드 배경 위에 완벽하게 위치합니다. 결론 기억하세요: 다음에 z-index가 제어할 수 없는 것처럼 보이면 이는 트랩된 스태킹 컨텍스트입니다. 참고자료
스태킹 컨텍스트(MDN) Z-색인 및 스태킹 컨텍스트(web.dev) "CSS의 격리 속성을 사용하여 새로운 스택 컨텍스트를 만드는 방법", Natalie Pina “도대체 z-index가 뭐죠??”, Josh Comeau
SmashingMag에 대한 추가 자료
“대규모 프로젝트에서 CSS Z-Index 관리”, Steven Frieson “고정 헤더와 전체 높이 요소: 까다로운 조합”, Philip Braunen "구성 요소 기반 웹 애플리케이션에서 Z-Index 관리", Pavel Pomerantsev “Z-Index CSS 속성: 포괄적인 모양”, Louis Lazaris