Positioned layout/Stacking floating elements

김동현·2026년 3월 21일

mdn 학습 번역 - CSS

목록 보기
135/190

안녕하세요! 프론트엔드 강사입니다. 오늘은 CSS에서 요소들이 겹칠 때 누가 위로 올라오고 누가 아래로 깔리는지 결정하는 '쌓임 순서(Stacking order)', 그중에서도 골칫거리인 '플로팅(Floating) 요소'가 끼어있을 때의 규칙을 MDN 문서를 통해 알아보겠습니다.

과거에는 레이아웃을 잡을 때 float을 정말 많이 썼기 때문에 이 규칙을 모르면 화면이 엉망진창이 되곤 했죠. 요즘은 Flexbox나 Grid를 많이 쓰지만, 레거시 코드를 유지보수하거나 텍스트 주변으로 이미지를 예쁘게 감쌀 때는 여전히 float의 원리를 잘 알아야 합니다. 제가 실무 팁과 함께 알기 쉽게 풀어서 설명해 드릴게요!


플로팅 요소의 쌓임 (Stacking floating elements)

화면에 둥둥 떠 있는 플로팅(floating) 요소들의 경우, 쌓임 순서(stacking order)가 일반적인 요소들과는 조금 다릅니다. 플로팅 요소들은 '위치가 지정되지 않은(non-positioned) 요소'와 '위치가 지정된(positioned) 요소' 바로 그 사이에 쏙 들어가게 배치됩니다.

구체적인 쌓임 순서는 아래에서부터 위로 다음과 같습니다 (번호가 낮을수록 바닥에 깔리고, 높을수록 화면 앞쪽으로 튀어나옵니다):

  1. 루트(root) 요소의 배경(background)과 테두리(borders). (보통 <html>이나 <body> 태그의 배경이 제일 밑바닥에 깔리죠.)
  2. 위치가 지정되지 않은(non-positioned) 자손 요소들. (HTML 문서에 작성된 순서대로 차곡차곡 쌓입니다.)
  3. 플로팅 요소들 (Floating elements)
  4. 위치가 지정된(positioned) 자손 요소들. (HTML 문서에 작성된 순서대로 쌓입니다.)

위치가 지정된 요소(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을 준 것과 비슷한 효과가 나면서 레이아웃 층이 엉켜버리니 항상 조심하세요!


이 문서의 목차


예제 (Example)

아래 예제를 보면 아주 흥미로운 사실을 알 수 있습니다. 위치가 지정되지 않은 요소(DIV #4)의 '배경색과 테두리'는 플로팅 요소의 영향을 전혀 받지 않고 그 아래에 쫙 깔려있지만, 그 안의 '텍스트(content)'는 플로팅 요소에 밀려서 옆으로 비켜나 있다는 점입니다.

이것은 플로팅 요소의 표준 동작 방식 때문입니다. 방금 위에서 배웠던 4단계 리스트에 새로운 규칙 하나를 추가해서 아주 정확한 쌓임 순서를 다시 정리해 보겠습니다:

  1. 루트 요소의 배경과 테두리.
  2. 위치가 지정되지 않은(non-positioned) 자손 요소들 (이들의 배경과 블록 박스). HTML 순서대로 쌓임.
  3. 플로팅 요소들.
  4. 위치가 지정되지 않은 자손 인라인(inline) 요소들 (즉, 텍스트나 이미지 같은 실제 내용물들).
  5. 위치가 지정된(positioned) 자손 요소들. HTML 순서대로 쌓임.

👨‍🏫 강사님의 꿀팁 & 보충설명:
4번 규칙이 바로 float의 존재 이유입니다! float은 원래 텍스트가 이미지를 자연스럽게 감싸안고 흐르도록(flow) 만들기 위해 발명된 속성이에요.
그래서 박스의 배경(2번)은 둥둥 뜬 이미지(3번) 밑으로 무시하고 깔려 들어가지만, 그 박스 안의 글씨(4번)들은 이미지 밑에 깔려서 안 보이면 안 되기 때문에 이미지보다 한 층 위로 올라와서 이미지를 피해 옆으로 비켜서게 되는 겁니다.
정말 똑똑하면서도 헷갈리는 설계죠?

HTML

아래는 다양한 위치 속성을 가진 박스들을 겹쳐놓은 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>

CSS

각 박스에 색상과 위치를 지정해 줍니다. 겹치는 모양을 잘 확인해 보세요.

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;
}

결과 (Result)

이 코드를 브라우저에서 실행하면 층층이 겹쳐진 박스들을 볼 수 있습니다.

실행 결과를 자세히 관찰해 보세요:
1. 노란색 DIV #4 (no positioning)의 테두리와 배경은 양쪽의 초록색 float 박스들 밑에 깔려 있습니다.
2. 하지만 DIV #4 안에 적힌 텍스트들은 초록색 박스 밑에 깔리지 않고 가운데로 밀려나와서 잘 보이죠?
3. 빨간색 테두리의 DIV #1, DIV #5 (position: absolute) 와 파란색 배경의 DIV #6 (position: relative)는 가장 꼭대기 층에 있어서 초록색 float 박스들을 덮어버리고 제일 위에 뜹니다.


같이 보기 (See also)

z-index와 쌓임 순서에 대해 완벽하게 마스터하고 싶다면 아래 링크들도 꼼꼼히 읽어보시길 강력히 추천합니다!


MDN 개선에 도움을 주세요 (Help improve MDN)

이 페이지가 도움이 되었나요? (Was this page helpful to you?)

이 페이지는 MDN 기여자들에 의해 2025년 11월 7일에 마지막으로 수정되었습니다.


수고하셨습니다! 이제 화면에 요소들을 배치할 때 어떤 놈이 위로 올라오고 가려지는지 완벽하게 컨트롤할 수 있겠죠? 이 원리만 알면 나중에 z-index를 쓸 때도 훨씬 수월해질 겁니다. 복습 꼭 해보시고 모르는 건 언제든 질문 주세요!

profile
프론트에_가까운_풀스택_개발자

0개의 댓글