안녕하세요! 프론트엔드 강사입니다. 오늘은 CSS에서 요소들이 겹칠 때 누가 위로 올라오고 누가 아래로 깔리는지 결정하는 '쌓임 순서(Stacking order)', 그중에서도 골칫거리인 '플로팅(Floating) 요소'가 끼어있을 때의 규칙을 MDN 문서를 통해 알아보겠습니다.
과거에는 레이아웃을 잡을 때 float을 정말 많이 썼기 때문에 이 규칙을 모르면 화면이 엉망진창이 되곤 했죠. 요즘은 Flexbox나 Grid를 많이 쓰지만, 레거시 코드를 유지보수하거나 텍스트 주변으로 이미지를 예쁘게 감쌀 때는 여전히 float의 원리를 잘 알아야 합니다. 제가 실무 팁과 함께 알기 쉽게 풀어서 설명해 드릴게요!
화면에 둥둥 떠 있는 플로팅(floating) 요소들의 경우, 쌓임 순서(stacking order)가 일반적인 요소들과는 조금 다릅니다. 플로팅 요소들은 '위치가 지정되지 않은(non-positioned) 요소'와 '위치가 지정된(positioned) 요소' 바로 그 사이에 쏙 들어가게 배치됩니다.
구체적인 쌓임 순서는 아래에서부터 위로 다음과 같습니다 (번호가 낮을수록 바닥에 깔리고, 높을수록 화면 앞쪽으로 튀어나옵니다):
<html>이나 <body> 태그의 배경이 제일 밑바닥에 깔리죠.)위치가 지정된 요소(position: relative | absolute | fixed | sticky)와 위치가 지정되지 않은 요소(position: static, 즉 기본값)에 대한 명확한 설명은 위치 지정의 유형(types of positioning) 문서를 참고해 보세요.
👨🏫 강사님의 꿀팁 & 보충설명:
이 순서를 외우는 가장 쉬운 방법은 "기본 요소(Static) < 둥둥 뜬 요소(Float) < 위치 잡은 요소(Position)" 순으로 화면 앞쪽으로 튀어나온다고 기억하는 것입니다!
만약 텍스트 박스(static)가 있고, 그 위에 이미지(float)를 띄우고, 또 그 위에 'New!' 같은 배지(position: absolute)를 붙이면 이 순서대로 완벽하게 겹쳐지게 됩니다.
주의 (Note):
만약 위치가 지정되지 않은 요소(아래 예제의 DIV #4 같은 것)에 opacity(투명도) 값을 주게 되면 아주 이상한 일이 벌어집니다! 그 블록의 배경과 테두리가 갑자기 플로팅 블록이나 위치가 지정된 블록들보다 더 위로 튀어나와 버려요.
이것은 CSS 스펙의 아주 특이한 부분 때문인데, 요소에 opacity 값을 적용하면 '새로운 쌓임 맥락(Stacking context)'이 만들어지기 때문입니다. 이에 대한 자세한 내용은 아무도 알려주지 않았던 Z-Index의 비밀(What No One Told You About Z-Index) 글을 참고해 보세요.
👨🏫 강사님의 꿀팁:
방금 읽으신 Note 부분은 실무에서 정말 뼈아픈 버그를 많이 만들어내는 범인입니다! "어? 왜 z-index를 안 줬는데 갑자기 팝업 위로 이 박스가 올라오지?" 하고 코드를 뒤져보면 십중팔구 누군가opacity: 0.9같은 걸 줘서 쌓임 맥락이 새로 생겨버린 경우입니다.opacity뿐만 아니라transform,filter같은 속성도 1 미만의 값을 주면 억지로z-index: 0을 준 것과 비슷한 효과가 나면서 레이아웃 층이 엉켜버리니 항상 조심하세요!
아래 예제를 보면 아주 흥미로운 사실을 알 수 있습니다. 위치가 지정되지 않은 요소(DIV #4)의 '배경색과 테두리'는 플로팅 요소의 영향을 전혀 받지 않고 그 아래에 쫙 깔려있지만, 그 안의 '텍스트(content)'는 플로팅 요소에 밀려서 옆으로 비켜나 있다는 점입니다.
이것은 플로팅 요소의 표준 동작 방식 때문입니다. 방금 위에서 배웠던 4단계 리스트에 새로운 규칙 하나를 추가해서 아주 정확한 쌓임 순서를 다시 정리해 보겠습니다:
👨🏫 강사님의 꿀팁 & 보충설명:
4번 규칙이 바로float의 존재 이유입니다!float은 원래 텍스트가 이미지를 자연스럽게 감싸안고 흐르도록(flow) 만들기 위해 발명된 속성이에요.
그래서 박스의 배경(2번)은 둥둥 뜬 이미지(3번) 밑으로 무시하고 깔려 들어가지만, 그 박스 안의 글씨(4번)들은 이미지 밑에 깔려서 안 보이면 안 되기 때문에 이미지보다 한 층 위로 올라와서 이미지를 피해 옆으로 비켜서게 되는 겁니다.
정말 똑똑하면서도 헷갈리는 설계죠?
아래는 다양한 위치 속성을 가진 박스들을 겹쳐놓은 HTML 코드입니다.
<div id="abs1"><strong>DIV #1</strong><br />position: absolute;</div>
<div id="flo1"><strong>DIV #2</strong><br />float: left;</div>
<div id="flo2"><strong>DIV #3</strong><br />float: right;</div>
<br />
<div id="sta1"><strong>DIV #4</strong><br />no positioning</div>
<div id="abs2"><strong>DIV #5</strong><br />position: absolute;</div>
<div id="rel1"><strong>DIV #6</strong><br />position: relative;</div>
각 박스에 색상과 위치를 지정해 줍니다. 겹치는 모양을 잘 확인해 보세요.
div {
padding: 10px;
text-align: center;
}
strong {
font-family: sans-serif;
}
#abs1 {
position: absolute;
width: 150px;
height: 200px;
top: 10px;
right: 140px;
border: 1px dashed #990000;
background-color: #ffdddd;
}
#sta1 {
height: 100px;
border: 1px dashed #999966;
background-color: #ffffcc;
margin: 0px 10px;
text-align: left;
}
#flo1 {
margin: 0px 10px 0px 20px;
float: left;
width: 150px;
height: 200px;
border: 1px dashed #009900;
background-color: #ccffcc;
}
#flo2 {
margin: 0px 20px 0px 10px;
float: right;
width: 150px;
height: 200px;
border: 1px dashed #009900;
background-color: #ccffcc;
}
#abs2 {
position: absolute;
width: 150px;
height: 100px;
top: 80px;
left: 100px;
border: 1px dashed #999900;
background-color: #ffdddd;
}
#rel1 {
position: relative;
border: 1px dashed #999966;
background-color: #ccffff;
margin: 0px 10px;
text-align: left;
}
이 코드를 브라우저에서 실행하면 층층이 겹쳐진 박스들을 볼 수 있습니다.
실행 결과를 자세히 관찰해 보세요:
1. 노란색 DIV #4 (no positioning)의 테두리와 배경은 양쪽의 초록색 float 박스들 밑에 깔려 있습니다.
2. 하지만 DIV #4 안에 적힌 텍스트들은 초록색 박스 밑에 깔리지 않고 가운데로 밀려나와서 잘 보이죠?
3. 빨간색 테두리의 DIV #1, DIV #5 (position: absolute) 와 파란색 배경의 DIV #6 (position: relative)는 가장 꼭대기 층에 있어서 초록색 float 박스들을 덮어버리고 제일 위에 뜹니다.
z-index와 쌓임 순서에 대해 완벽하게 마스터하고 싶다면 아래 링크들도 꼼꼼히 읽어보시길 강력히 추천합니다!
z-index 속성 없이 쌓기 (Stacking without the z-index property)이 페이지가 도움이 되었나요? (Was this page helpful to you?)
[예 (Yes)]
[아니요 (No)]
이 페이지는 MDN 기여자들에 의해 2025년 11월 7일에 마지막으로 수정되었습니다.
수고하셨습니다! 이제 화면에 요소들을 배치할 때 어떤 놈이 위로 올라오고 가려지는지 완벽하게 컨트롤할 수 있겠죠? 이 원리만 알면 나중에 z-index를 쓸 때도 훨씬 수월해질 겁니다. 복습 꼭 해보시고 모르는 건 언제든 질문 주세요!