퀴즈로 풀어보는 CSS z-index 속성의 3가지 포인트

웹 페이지가 다이나믹해지고 요소들의 배치가 자유로워지면, 때때로 서로의 위치가 겹치는 요소들이 생기기 마련입니다. 이 때 어느 것을 위에 표시할 것인가를 제어하는 CSS 속성이 다름 아닌 z-index입니다. 그만큼 자주 접하게 되는 속성입니다만, 한편으로는 오해하기 쉬운 몇가지 특징을 가진 속성이기도 합니다.

이번 포스팅에서는 z-index에 대한 중요한 포인트를 3가지 퀴즈를 통해 알아봅니다. (이 질문은 제가 신입 개발자들을 교육할 때 실제로 사용하고 있는 질문이기도 합니다.) 이 3가지 질문에 대해 정확하게 답을 하고 원리를 설명하실 수 있다면, 실무에서 만나는 대부분의 상황에서는 z-index 속성을 사용하는 데에는 큰 문제가 없으실 것입니다.

z-index의 정확한 사양에 대해서는 CSS Specification의 9.9.1 Specifying the stack level: the ‘z-index’ property 항목에서 다루고 있습니다. 좀더 자세한 정보가 필요하실 때에 함께 읽어보시기 바랍니다.

 

Q1. CSS가 아래와 같이 작성되어 있을 때, HTML 코드에 있는 3개의 <div>를 상위에 표시되는 순서대로 나열하세요.

#first
{
	z-index		: 30;
	width		: 200px;
	height		: 200px;
	background	: #3366cc;
}
#second
{
	z-index		: 20;
	width		: 200px;
	height		: 200px;
	margin-top	: -100px;
	background	: #cc3333;
}
#third
{
	z-index		: 50;
	width		: 200px;
	height		: 200px;
	margin-top	: -100px;
	margin-left	: 100px;
	background	: #ffaa33;
}
<div id="first">
	1st Box
</div>
<div id="second">
	2nd Box 
	<div id="third">3rd Box</div>
</div>

3개의 <div> 태그가 있습니다. 크기는 모두 가로세로 200픽셀입니다. 2번째와 3번째 <div>는 margin-top 속성이 -100픽셀로 되어 있어, 원래 위치보다 위로 100픽셀 이동하여 보일 것입니다. <div>를 상위에 나오는 순서대로 나열하면 어떻게 될까요?

 

A1. 3rd – 2nd – 1st

z-index 함정퀴즈 #1 정답

많은 분들의 예상과 다르게 정답은 왼쪽과 같습니다. 2nd보다 1st가 z-index 속성에 입력된 값이 더 높기 때문에, 이 정답은 상당히 의외로 느껴질 수 있습니다. 여기에 우리가 기억해야 하는 z-index의 첫 번째 함정이 있습니다.

z-index 값을 지정하기 위해서는 해당 요소의 position 속성이 relative, absolute, fixed 중 하나여야만 한다.

CSS Specification를 살펴보면 z-index 속성의 적용대상은 positioned elements, 즉 position 속성이 설정된 요소로 제한되어 있습니다. 그러나 문제에 등장한 3개의 <div>는 어느 것 하나도 position 속성이 지정되어 있지 않았습니다. 이처럼 position 속성이 지정되지 않은 상태라면, 이 요소들은 z-index가 0인 것처럼 작동합니다. HTML 소스 상에서 나중에 등장하는 요소가 앞에 나온 요소를 덮어버리게 됩니다. 그림을 그릴 때 앞서 칠한 물감을 나중에 칠한 물감이 덮는 것과 같이 말이죠.

 

Q2. CSS가 아래와 같이 작성되어 있을 때, HTML 코드에 있는 3개의 <div>를 상위에 표시되는 순서대로 나열하세요.

#first
{
	position	: relative; 
	z-index		: 30;
	width		: 200px;
	height		: 200px;
	background	: #3366cc;
}
#second
{
	position	: relative; 
	z-index		: 20;
	width		: 200px;
	height		: 200px;
	margin-top	: -100px;
	background	: #cc3333;
}
#third
{
	position	: relative;
	z-index		: 50;
	width		: 200px;
	height		: 200px;
	margin-top	: -100px;
	margin-left	: 100px;
	background	: #ffaa33;
}
<div id="first">
	1st Box
</div>
<div id="second">
	2nd Box 
	<div id="third">3rd Box</div>
</div>

이번 문제에서 등장한 소스코드는 첫 번째 문제의 소스코드에서 각 <div>에 position 속성만 추가로 지정한 것입니다. position 속성은 모두 relative로 설정되었고, top과 left 속성은 지정되지 않았으므로 위치의 변동은 없을 것입니다. <div>를 상위에 나오는 순서대로 나열하면 어떻게 될까요?

 

A2. 1st – 3rd – 2nd

z-index 함정퀴즈 #2 정답이번에야말로 z-index가 큰 순서대로 표시될 것이라고 예상하셨다면, 다시 한 번 예상이 빗나간 결과를 발견하게 됩니다. 우리가 기억해야 하는 z-index의 두 번째 함정이 여기에 있기 때문입니다.

z-index의 값은 같은 depth의 요소끼리 비교하는 것이 원칙이다.

z-index 값은 같은 depth에 있는 형제 요소(Siblings) 간에 비교하여 상하를 결정하는 것이 원칙이며, 자식 요소는 부모 요소의 비교결과를 따라가게 됩니다. 위 코드의 경우에는 형제간인 1st와 2nd를 비교하여 이미 1st가 상위에 있는 것으로 결론내렸기 때문에, 2nd의 자식 요소인 3rd는 아무리 높은 z-index 값을 주어도 1st보다 상위에 표시되지 않습니다.

 

Q3. CSS가 아래와 같이 작성되어 있을 때, HTML 코드에 있는 3개의 <div>를 상위에 표시되는 순서대로 나열하세요.

#first
{
	position	: relative; 
	z-index		: 30;
	width		: 200px;
	height		: 200px;
	background	: #3366cc;
}
#second
{
	position	: relative; 
	/*z-index	: 20;*/
	width		: 200px;
	height		: 200px;
	margin-top	: -100px;
	background	: #cc3333;
}
#third
{
	position	: relative;
	z-index		: 50;
	width		: 200px;
	height		: 200px;
	margin-top	: -100px;
	margin-left	: 100px;
	background	: #ffaa33;
}
<div id="first">
	1st Box
</div>
<div id="second">
	2nd Box 
	<div id="third">3rd Box</div>
</div>

두 번째 문제의 소스코드에서 #second 요소의 z-index 값을 주석처리 하였습니다. 그 외에는 어떠한 변경된 내용도 없습니다. <div>를 상위에 나오는 순서대로 나열하면 어떻게 될까요?

 

A3. 3rd – 1st – 2nd

z-index 함정퀴즈 #3 정답

이 문제의 경우, 1st – 3rd – 2nd라는 오답이 나오기 쉽습니다. 오답의 원인은 바로 z-index의 기본값이 정수 0일 것이라고 잘못 추측하는 데에 있습니다. 우리가 기억해야 하는 z-index의 세 번째 함정은 z-index의 기본값에 관한 것입니다.

z-index의 기본값은 auto이며, 이 경우 브라우저는 그 요소를 제쳐두고 자식 요소의 z-index 값을 비교대상으로 삼는다.

z-index에 아무런 값이 지정되지 않은 경우, 기본값은 auto가 됩니다. z-index가 auto로 지정된 요소는 z-index가 0으로 입력된 것처럼 작동하는 동시에, z-index 값의 비교대상을 자식 요소에게 넘겨줍니다. 위 코드에서는 2nd의 z-index가 auto이므로, 1st와 z-index를 비교할 대상은 3rd가 됩니다. 비교 결과 3rd의 z-index가 1st의 z-index보다 더 높으므로, 결과적으로 3rd가 가장 위에 표시되는 결과를 보게 됩니다.

그렇다면 우리는 왜 z-index의 기본값을 0으로 잘못 알고 있을까요. 이유는 바로 Internet Explorer 7의 버그 때문입니다. 당시 웹 브라우저 시장을 장악하고 있던 IE7에는 한 가지 버그가 있었는데, 그것이 다름 아닌 z-index의 기본값을 auto가 아닌 0으로 지정하는 것이었습니다. 이로 인하여 많은 웹 개발자들에게 잘못된 경험이 축적되었고 지금에 이르게 된 것입니다.

 

정리

금번 포스팅의 내용을 토대로 z-index의 주요 포인트를 정리하면, 아래와 같습니다.

  1. z-index 속성은 대게 정수값을 가지며, 높은 숫자를 가진 요소가 상위에 표시됩니다. 같은 z-index 간에는 HTML 코드상 나중에 등장하는 요소가 상위에 표시됩니다.
  2. z-index 값을 지정하기 위해서는 해당 요소의 position 속성이 relative, absolute, fixed 중 하나여야만 합니다.
  3. z-index의 값은 같은 depth의 요소끼리 비교하는 것이 원칙입니다.
  4. z-index의 기본값은 auto이며, 이 경우 브라우저는 그 요소를 제쳐두고 자식 요소의 z-index 값을 비교대상으로 삼습니다. (단, Internet Explorer 7에서는 z-index의 기본값이 0인 버그가 있습니다.)

CSS display 속성을 이해하기 위한 6가지 포인트

CSS의 display는 많은 다양한 상황에서 익숙하게 사용되는 속성입니다. 그러나 익숙한 데에는 언제나 함정이 있습니다. 실제로 display 속성을 사용하다보면 잘 알려지지 않은 특징들을 만나게 되는데, 이를 미리알고 대처하지 못하여 예상치 못한 곳에서 시간과 노력을 허비하는 상황을 만나게 됩니다.

이번 포스팅에서는 display 속성에 대해 6가지 포인트로 정리하였습니다. 이 포스팅은 display 속성에 대한 중요한 내용을 발췌하여 정리한 것이지만, 모든 것을 망라하고 있지는 않습니다. 부족한 부분에 대해서는 공식표준인 CSS 2.1 Specification 가운데 9.2.4 The ‘display’ property 항목을 참조하여 주시기 바랍니다.

Continue reading