안녕하세요! 프론트엔드 개발의 세계로 오신 것을 진심으로 환영합니다. 저는 여러분의 CSS 여정을 함께할 강사입니다.
오늘 우리가 정복할 주제는 바로 '플롯(Floats)'입니다. 과거 웹 개발의 역사에서 정말 애증의 대상이었던 속성이죠. 예전 코드를 보거나 유지보수할 때 반드시 알아야 하지만, 현대(Modern) 웹 개발에서는 그 역할이 확연히 달라졌습니다. 공식 문서의 내용을 하나도 빠짐없이 꼼꼼히 번역해 드리면서, 제가 실무에서 구르며 얻은 '진짜 실무 꿀팁'과 역사까지 재미있게 덧붙여 설명해 드릴게요. 자, 시작해볼까요?
원래 텍스트 블록 안에 이미지를 띄워(float) 글자가 자연스럽게 감싸도록 만들기 위해 도입되었던 float 속성은, 한때 웹페이지에서 다단(multiple column) 레이아웃을 만드는 데 가장 흔하게 쓰이는 도구가 되기도 했습니다. 하지만 Flexbox와 Grid라는 강력한 레이아웃 기술이 등장하면서, 이 문서에서 설명하는 바와 같이 이제는 다시 본래의 목적(텍스트 어울림)으로 돌아가게 되었습니다.
| 선행 조건 (Prerequisites): | HTML로 콘텐츠 구조화하기, CSS 스타일링 기초, 기본적인 텍스트와 폰트 스타일링, CSS 레이아웃 기초 개념에 대한 이해. |
| 학습 목표 (Learning outcomes): |
|
float 속성은 웹 개발자들이 텍스트 단락 안에 이미지를 '띄워놓고(floating)', 텍스트가 그 이미지의 왼쪽이나 오른쪽을 자연스럽게 감싸며 흐르도록(wrap around) 만들 수 있게 해주기 위해 도입되었습니다. 마치 신문이나 잡지 기사에서 흔히 볼 수 있는 레이아웃처럼 말이죠.
하지만 웹 개발자들은 곧 "이미지뿐만 아니라 뭐든지 띄울 수 있네?"라는 사실을 깨달았습니다. 그래서 플롯의 용도는 점점 넓어져서, 문단의 첫 글자만 대문짝만하게 키우는 드롭 캡스(drop-caps) 같은 재미있는 레이아웃 효과를 만드는 데도 쓰이게 되었습니다.
나아가 플롯은 웹사이트 전체의 레이아웃을 구축하는 데 아주 광범위하게 사용되었습니다. 여러 개의 정보 단단을 나란히 옆으로 배치하기 위해 모든 단을 플롯 시키는 식이었죠. (플롯을 쓰지 않으면 HTML 소스 코드에 나타난 순서대로 위에서 아래로 차곡차곡 쌓이는 것이 기본 동작이니까요). 하지만 이제는 더 새롭고 훌륭한 레이아웃 기술(Flexbox, Grid)들이 존재합니다. 따라서 레이아웃 전체를 잡기 위해 플롯을 사용하는 것은 이제 구시대의 유물(legacy technique)로 간주해야 합니다.
이번 문서에서는 오직 플롯의 '올바른(원래의)' 용도에 대해서만 집중적으로 다루겠습니다.
💡 강사님의 실무 팁!
"강사님, 그럼 실무에서 float은 언제 쓰나요?"
딱 잘라 말씀드릴게요. 레이아웃(화면 분할)을 잡을 때는 절대, 네버 쓰지 마세요! Flexbox나 CSS Grid를 쓰셔야 합니다. 요즘 실무에서float이 쓰이는 경우는 오직 하나, 블로그 글이나 기사 본문에서 '이미지 옆으로 텍스트가 자연스럽게 흘러가게(Text Wrapping)' 만들고 싶을 때뿐입니다.
플롯의 사용법을 직접 탐구해 봅시다. 어떤 요소(박스) 주위로 텍스트 블록이 감싸듯 흐르게 만드는 예제부터 시작할 거예요. 컴퓨터에 새로운 index.html 파일을 만들고, HTML 템플릿을 채워 넣은 뒤, 알맞은 위치에 아래 코드들을 차례대로 붙여넣으면서 따라와 보세요. (이 섹션 맨 아래에서 최종적으로 완성된 라이브 예제를 보실 수 있습니다.)
먼저 HTML부터 시작합니다. HTML 문서의 <body> 태그 안쪽에 기존에 있던 내용은 싹 지우고 아래 코드를 추가하세요:
<h1>Float example</h1>
<div class="box">Float</div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam
dolor, eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus
ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus
laoreet sit amet.
</p>
<p>
Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet
orci vel, viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare
ex malesuada et. In vitae convallis lacus. Aliquam erat volutpat. Suspendisse
ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis
ornare egestas augue ut luctus. Proin blandit quam nec lacus varius commodo et
a urna. Ut id ornare felis, eget fermentum sapien.
</p>
<p>
Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada
ultrices. Phasellus turpis est, posuere sit amet dapibus ut, facilisis sed
est. Nam id risus quis ante semper consectetur eget aliquam lorem. Vivamus
tristique elit dolor, sed pretium metus suscipit vel. Mauris ultricies lectus
sed lobortis finibus. Vivamus eu urna eget velit cursus viverra quis
vestibulum sem. Aliquam tincidunt eget purus in interdum. Cum sociis natoque
penatibus et magnis dis parturient montes, nascetur ridiculus mus.
</p>
이제 다음 CSS를 HTML에 적용하세요 (<style> 태그 안에 넣거나, 별도의 .css 파일로 만들어서 <link>로 연결해도 됩니다. 편한 대로 하세요!):
body {
width: 90%;
max-width: 900px;
margin: 0 auto;
font:
0.9em/1.2 "Helvetica",
"Arial",
sans-serif;
}
.box {
width: 150px;
height: 100px;
border-radius: 5px;
background-color: rgb(207 232 220);
padding: 1em;
}
저장하고 브라우저를 새로고침 해보면, 여러분이 예상한 바로 그 모습이 나올 겁니다. 박스가 글자들 위에 떡하니 한자리를 차지하고, 일반적인 흐름(normal flow)에 따라 텍스트는 그 아래에 밀려나 있는 모습이죠.
이제 이 박스를 '띄워(float)' 봅시다. .box CSS 규칙 안에 float과 margin-right 속성을 추가해 보세요:
.box {
float: left;
margin-right: 15px;
width: 150px;
height: 100px;
border-radius: 5px;
background-color: rgb(207 232 220);
padding: 1em;
}
이제 저장하고 새로고침을 하면, 아래와 같이 놀라운 변화가 생긴 것을 볼 수 있습니다:
MDN Playground에서 직접 예제 코드 만져보기
이 플롯이 어떻게 작동하는지 원리를 생각해 볼까요? 플롯이 설정된 요소(이 경우에는 <div> 태그)는 문서의 일반적인 레이아웃 흐름(normal layout flow)에서 쏙 빠져나와서, 자신을 감싸고 있는 부모 컨테이너(여기서는 <body>)의 왼쪽 벽에 착 달라붙게 됩니다.
그러면 원래대로라면 이 띄워진 요소 '아래'에 자리 잡아야 했을 일반적인 콘텐츠(글자들)가, 이제는 이 플롯 된 요소의 오른쪽 빈 공간을 메우며 위로 스멀스멀 기어 올라와 주변을 감싸듯 흐르게(wrap around) 됩니다. 텍스트는 플롯 된 요소의 꼭대기 높이까지만 올라가며, 그 이상 올라가지는 못하고 멈춥니다.
콘텐츠를 오른쪽으로 띄우는 것도 똑같은 원리지만 방향만 반대입니다. 요소가 오른쪽 벽에 착 달라붙고, 글자들이 왼쪽 빈 공간을 채우며 흐르겠죠. 방금 작성한 코드에서 float 값을 right로 바꾸고, margin-right 대신 margin-left로 변경한 뒤 어떤 결과가 나오는지 직접 테스트해 보세요!
우리가 플롯 된 요소(박스)에 margin을 줘서 텍스트를 밀어낼 수는 있지만, 반대로 텍스트 쪽에서 margin을 줘서 플롯 된 박스로부터 멀어지게 밀어낼 수는 없습니다. 왜냐고요? 플롯 된 요소는 일반적인 흐름(normal flow)에서 완전히 빠져나왔기 때문에, 플롯 된 요소 다음에 오는 아이템(단락)의 실제 '박스' 영역 자체는 플롯 된 요소의 등 뒤(behind)로 파고들어가서 렌더링 되기 때문입니다! 눈에 보이는 '글자'들만 플롯 된 박스를 피해 요리조리 피해서 흐르는 것뿐이죠.
이해를 돕기 위해 예제를 조금 수정해서 직접 눈으로 확인해 봅시다.
플롯 된 박스 바로 다음에 오는 첫 번째 단락(<p>) 태그에 special 이라는 클래스를 추가하세요. 그런 다음 CSS에 아래 규칙을 추가합니다. 이렇게 하면 이어지는 단락에 뚜렷한 배경색이 칠해집니다.
.special {
background-color: rgb(148 255 172);
padding: 10px;
color: purple;
}
효과를 더 확실히 보기 위해, 아까 박스에 줬던 margin-right 속성을 그냥 margin으로 바꿔서 박스 사방에 여백을 만들어주세요. 그러면 아래 예제처럼 단락의 배경색이 플롯 된 박스 '아래쪽으로(behind)' 쑥 파고 들어가 있는 것을 명확하게 볼 수 있습니다.
.box {
float: left;
margin: 15px;
width: 150px;
height: 150px;
border-radius: 5px;
background-color: rgb(207 232 220);
padding: 1em;
}
MDN Playground에서 직접 예제 코드 만져보기
이어지는 단락 요소의 라인 박스(line boxes)들(글자가 있는 줄)은 플롯을 피해서 텍스트가 흐를 수 있도록 짧아졌지만, 플롯이 일반 흐름에서 제거되었기 때문에 이 단락 전체를 감싸는 껍데기 박스 자체는 여전히 화면 전체 너비(full width)를 다 차지하고 있는 겁니다.
지금까지 플롯 된 요소는 일반 흐름에서 빠져나오고, 그 뒤에 오는 요소들이 그 옆으로 끌려 올라와 배치된다는 걸 확인했습니다. 그렇다면, 뒤에 오는 요소가 플롯 된 요소 옆으로 기어 올라오지 못하게 막고 싶다면 어떻게 해야 할까요?
바로 그럴 때 플롯의 영향을 해제(clear)해 주어야 하며, 이는 clear 속성으로 달성할 수 있습니다.
이전 예제의 HTML에서, 플롯 된 아이템 아래에 있는 두 번째 단락에 cleared라는 클래스를 추가해 보세요. 그런 다음 CSS에 다음 코드를 추가합니다:
.cleared {
clear: left;
}
MDN Playground에서 직접 예제 코드 만져보기
결과를 보시면 이제 두 번째 단락이 플롯 된 요소를 완전히 지나친(clear) 아래쪽으로 내려가서, 더 이상 박스 옆으로 나란히 올라오지 않는 것을 확인할 수 있습니다. clear 속성은 다음과 같은 값들을 받을 수 있습니다:
left: 왼쪽으로 플롯(float: left)된 요소들의 영향을 해제합니다.right: 오른쪽으로 플롯(float: right)된 요소들의 영향을 해제합니다.both: 왼쪽이든 오른쪽이든 방향에 상관없이 모든 플롯 된 요소의 영향을 해제합니다.💡 강사님의 실무 팁!
"아하, 플롯을 썼으면 그 영향력을 끊어내기 위해 어딘가에는clear를 써줘야 레이아웃이 안 꼬이는구나!" 라고 기억하시면 완벽합니다.
이제 플롯 된 요소 '뒤에' 오는 요소를 해제하는 방법은 알게 되었습니다. 하지만 길이가 긴 플롯 박스와 짧은 텍스트 단락이 있고, 이 둘을 함께 감싸는 부모 <div> 박스가 있다면 과연 어떤 끔찍한 일(?)이 벌어질까요?
여러분의 문서 구조를 조금 수정해서, 플롯 된 박스와 그 바로 뒤의 첫 번째 단락을 wrapper라는 클래스를 가진 <div>로 함께 감싸(wrap) 보세요.
<div class="wrapper">
<div class="box">Float1</div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus
aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci,
pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at
ultricies tellus laoreet sit amet.
</p>
</div>
그런 다음 CSS에 .wrapper 클래스를 위한 다음 규칙을 추가하고 페이지를 새로고침 해보세요:
.wrapper {
background-color: rgb(148 255 172);
padding: 10px;
color: purple;
}
헷갈리지 않게 아까 넣었던 기존 .cleared 클래스는 지워주시고요.
결과를 보시면, 아까 배경색을 넣었을 때와 똑같은 현상이 발생합니다. 감싸고 있는 부모 .wrapper의 배경색이 플롯 된 박스의 키(height)를 온전히 품지 못하고, 플롯 박스가 부모 영역을 뚫고 아래로 삐져나온 것을 볼 수 있죠!
MDN Playground에서 직접 예제 코드 만져보기
왜 이럴까요? 또 같은 이유입니다. 플롯 된 요소가 문서의 일반 흐름에서 쏙 빠져나갔기 때문입니다. 여러분은 부모 래퍼(wrapper) 박스가 플롯 된 요소와 텍스트를 모두 감싸고 있으니 당연히 그 높이만큼 늘어나서 품어줄 거라고 예상하셨겠지만, 브라우저 입장에서는 "어? 내 안에 플롯 된 애는 공중에 떠버렸네? 그럼 남은 건 짧은 텍스트뿐이니까 내 키(height)는 텍스트 높이까지만 잡아야지!" 하고 키를 확 줄여버린(collapse) 겁니다.
이것이 바로 프론트엔드 개발자들을 그토록 괴롭혔던 유명한 '플롯 높이 붕괴(Height Collapse) 현상'입니다.
이 고질적인 문제를 편법(hacks) 없이 아주 깔끔하게 해결하기 위해 탄생한 속성 값이 바로 display 속성의 flow-root 값입니다. 이 값은 오직 이 특정 문제를 해결하기 위해 도입되었으며, 사용했을 때 디자인에 아무런 부작용(unintended consequences)을 일으키지 않습니다.
자, 코드를 이렇게 수정해 보세요!
.wrapper {
background-color: rgb(148 255 172);
padding: 10px;
color: purple;
display: flow-root;
}
MDN Playground에서 직접 예제 코드 만져보기
짠! 이제 부모 래퍼(.wrapper)가 자신의 자식인 플롯 요소를 완전히 인지하고 그 높이만큼 정상적으로 쭈욱 늘어나서 품어주는 것을 확인할 수 있습니다.
💡 강사님의 실무 팁!
"어? 저는 예전에clearfix라는 걸 쓴다고 배웠는데요?"
맞습니다! 과거에는 이 높이 붕괴 현상을 해결하기 위해 부모 요소에 가상 요소(::after)를 만들고clear: both를 주는 이른바 clearfix 핵(hack)을 전 세계 모든 개발자가 사용했어요.
하지만 세상이 좋아졌죠! 최신 모던 브라우저들에서는 꼼수 없이 그저 부모 요소에display: flow-root;한 줄만 주면 이 모든 문제가 완벽하게 해결됩니다. 이제 clearfix는 역사 속으로 보내주셔도 좋습니다!
이것으로 여러분이 플롯(floats)에 대해 알아야 할 핵심 내용은 모두 끝났습니다! 생각보다 어렵지 않죠?
다음 문서에서는 오늘 배운 이 지식들을 얼마나 잘 이해하고 머릿속에 담아두었는지 확인해 볼 수 있는 재미있는 테스트(도전 과제)가 기다리고 있습니다.
기여하는 방법 알아보기 (Learn how to contribute)
이 페이지의 마지막 수정일은 Nov 7, 2025 이며, MDN 기여자들(MDN contributors)에 의해 작성되었습니다.
수고 많으셨습니다! 플롯의 세계에서 살아남으신 걸 축하드려요. 혹시 이해가 잘 안되시는 부분이 있다면 언제든 편하게 물어보시고, 준비되셨다면 다음 테스트로 넘어가 볼까요?