CSS z-index를 높여도 요소가 앞으로 나오지 않을 때: position 속성 확인법
웹 화면을 구성할 때 드롭다운 메뉴, 팝업, 헤더 바 등이 본문 콘텐츠 뒤로 숨어버리는 문제를 자주 겪습니다. 이때 z-index: 999나 심지어 z-index: 99999와 같이 매우 큰 숫자를 지정했는데도 화면에서 전혀 앞으로 나오지 않고 여전히 뒤쪽에 덮이는 현상이 발생합니다. 이는 CSS의 z-index 속성이 모든 HTML 요소에 무조건 적용되는 것이 아니라, 특정 배치 조건(위치 지정 상태)을 충족해야만 계층 순서 계산에 참여하기 때문입니다.
z-index가 작동하지 않는 근본 원인: 기본 위치 지정 상태
CSS 명세에서 z-index 속성은 위치가 지정된 요소(Positioned element)와 그 자손 요소, 또는 플렉스(Flex) 및 그리드(Grid) 아이템에 적용됩니다. 여기서 위치가 지정된 요소란 position 속성값이 static이 아닌 요소를 의미합니다.
HTML의 모든 일반 태그는 브라우저 기본 스타일로 position: static 상태를 가집니다. 따라서 아무런 position 값을 별도로 부여하지 않은 채 z-index 값만 정수로 지정하면, 브라우저는 해당 요소의 z-index 속성을 화면 계층 계산에 반영하지 않습니다. 결과적으로 HTML 문서 흐름(DOM 순서)에 따라 뒤에 선언된 요소가 앞선 요소를 자연스럽게 덮어쓰게 됩니다.
재현 상황과 예상 결과
실제 화면에서 상단 메뉴와 본문 영역이 겹칠 때 발생하는 상황을 재현해 보면 다음과 같습니다.
HTML에서 <div style="z-index: 999;">상단 메뉴</div> 뒤에 <div style="margin-top: -20px;">본문</div>이 오면 z-index가 높아도 본문이 메뉴를 덮습니다. 상단 메뉴에 'position: relative;'를 추가하면 z-index가 정상 반영되어 상단 메뉴가 본문 위로 올라옵니다.위 재현 코드에서 상단 메뉴는 z-index: 999를 가지고 있지만 position 속성을 선언하지 않아 기본값인 static 상태로 남아 있습니다. 그 뒤에 나타난 본문 영역이 음수 여백(margin-top: -20px;)을 통해 위로 끌어올려지면, HTML 순서상 나중에 나타난 본문이 상단 메뉴 위를 덮게 됩니다. 메뉴에 position: relative;를 명시하는 순간 비로소 위치 지정 요소로 인정받아 z-index: 999가 유효해지고, 본문 위로 올바르게 올라옵니다.
단계별 점검 및 안전한 수정 순서
요소가 뒤로 가려질 때는 무작정 숫자를 키우기보다 아래 순서대로 스타일을 점검하는 것이 안전합니다.
- 요소의 position 속성 확인: 가려지는 요소의 CSS를 열어
position속성이 선언되어 있는지 확인합니다. 아무런 선언이 없다면 브라우저는 기본값인static으로 간주합니다. - position: relative 추가: 원래의 문서 흐름과 레이아웃 위치를 그대로 유지하면서 위치 지정 상태로 만들기 위해 해당 요소에
position: relative;를 추가합니다. 기존 배치를 완전히 띄워야 하는 특수한 상황이라면absolute나fixed를 검토할 수 있습니다. - 형제 요소와의 z-index 대조: 가리고 있는 상대 요소의
position과z-index값을 확인합니다. 덮고 있는 요소 역시 위치 지정 상태이고z-index가 부여되어 있다면, 앞서 나와야 할 요소의 값이 더 큰 정수인지 비교합니다. - 개발자 도구에서 계층 확인: 브라우저 검사 도구(Elements 패널)에서 대상 요소의 계산된(Computed) 스타일 항목을 열어
position이static이외의 값으로 계산되고 있는지,z-index가 정상적으로 적용되었는지 확인합니다.
z-index 속성값과 동작 원리
MDN z-index 문서에 따르면 z-index는 정수값 또는 키워드 auto를 가집니다. 값의 종류에 따라 쌓임 맥락(Stacking Context) 생성 여부가 달라집니다.
| 속성값 | 위치 지정 요소에서의 동작 | 쌓임 맥락 생성 여부 |
|---|---|---|
| auto | 현재 쌓임 맥락에서 요소의 렌더링 순서 레벨을 0으로 둡니다. | 새로운 로컬 쌓임 맥락을 생성하지 않습니다. |
| <integer> | 지정한 정수가 현재 쌓임 맥락 내에서의 렌더링 순서 레벨이 됩니다. | 해당 요소가 새로운 로컬 쌓임 맥락을 생성합니다. |
정수값을 부여하면 해당 요소는 자체적인 로컬 쌓임 맥락을 형성합니다. 두 요소가 겹칠 때는 더 큰 z-index 값을 가진 요소가 작은 값을 가진 요소를 덮습니다. 음수 정수를 사용하면 우선순위를 낮출 수도 있습니다.
position을 주어도 해결되지 않는 실패 원인: 부모 쌓임 맥락
대상 요소에 position: relative;와 z-index: 9999를 분명히 주었는데도 다른 요소 아래에 깔려 있다면, 원인은 대부분 부모 요소가 만든 ‘독립된 쌓임 맥락’에 있습니다.
자식 요소가 z-index: 9999를 갖더라도, 그 부모 요소 A가 z-index: 1을 가진 위치 지정 요소이고 인접한 형제 요소 B가 z-index: 2를 가지고 있다면, 자식 요소는 결코 형제 요소 B 위로 올라갈 수 없습니다. 로컬 쌓임 맥락이 생성되면 자손 요소의 z-index는 해당 로컬 맥락 안에서만 비교될 뿐, 바깥 맥락에 위치한 요소와의 순서 경쟁에 직접 참여하지 못하기 때문입니다. 따라서 자식의 숫자를 끝없이 올리지 말고, 상위 부모 요소들의 z-index 계층과 구조를 점검해야 합니다.
점검 방법의 한계와 주의사항
본문에서 다룬 position: relative; 추가 방법은 단일 계층 내에서 position: static 때문에 z-index가 무시되던 문제를 해결하는 기준점입니다. 그러나 다음과 같은 한계가 있으므로 주의 깊게 구분해야 합니다.
- 복잡한 부모 트리 분석 한계:
position: relative;를 추가하는 것만으로는 상위 부모 태그가 생성한 다른 쌓임 맥락과의 충돌을 자동으로 풀어내지 못합니다.z-index문제를 완전히 진단하려면 덮고 있는 요소와 가려진 요소의 공통 부모를 찾아 트리 전체의 계층 구조를 함께 확인해야 합니다. - 스타일 충돌 위험: 기존에 다른 레이아웃 계산을 위해
top,left등이 사전에 지정되어 있던 요소라면,position을relative나absolute로 변경할 때 예기치 않은 좌표 이동이 발생할 수 있으므로 위치 관련 속성이 함께 걸려 있는지 사전에 점검해야 합니다.
참고 자료와 확인 범위
아래 자료는 형식·기능의 정의를 확인하는 데 사용했습니다. 본문의 예제와 설명은 이 사이트의 작업 상황에 맞춰 구성했습니다. 제품 메뉴는 버전과 언어에 따라 다를 수 있습니다.
확인일: 2026-10-27 · 오류를 발견하면 이 글의 오류 신고로 알려주세요.