float을 clear하는 4가지 방법.
CSS 속성 가운데 float 속성은 자기 자신의 위치를 주변의 콘텐츠로부터 상대적으로 배치하는 속성입니다. float은 사전적 의미로 ‘뜨다, 띄우다, 뜨는 물건, 부유물’ 이라는 의미가 담겨져 있습니다. float은 높이가 가변적인 다단 컬럼 형태의 CSS 레이아웃을 위하여 반드시 요구되는 속성으로서 처음 CSS 배치기법을 익힐 때 가장 이해하기 어려운 속성중의 하나 입니다. float 속성이 부여된 엘리먼트는 좌측이나 우측으로 배치되면서 주변 콘텐츠의 배치에도 영향을 미친다는 사실은 어렵지 않게 학습되나 ‘float 된 엘리먼트가 부모 엘리먼트의 높이에 영향을 주지 않는다는 사실’은 몇 번의 경험 또는 선배들의 조언으로 깨닫게 되는 것이지요.
오늘은 float 속성을 이해하고 다단 컬럼형 레이아웃을 시도할 때 주변 엘리먼트들이 원하는 상태로 배치될 수 있도록 이것에 대응하거나 clear 하는 방법에 대하여 공유하고자 합니다. clear 속성은 float이 더이상 주변 엘리먼트의 배치에 영향을 미치지 않도록 해제시키는 속성입니다. 만약 Internet Explorer 브라우저를 사용하여 학습을 시도하신다면 일단 멈추시고 표준계열 브라우저에서 먼저 시도해 보세요. CSS 표준 렌더링을 엄격하게 준수하는 Opera와 Safari를 권장합니다. Internet Explorer와 Firefox 브라우저는 float, clear 속성에 관한 버그를 포함하고 있으므로 float과 clear의 표준 렌더링이 어떻게 구현되는지를 학습할 때 도움이 되지 않습니다. 하지만 버그를 해결하는 방법도 소개되어 있으니 안심하세요.
오늘 글의 핵심은 ‘float된 자식 엘리먼트의 높이를 부모 엘리먼트에 반영하도록 대응하는 방법’ 이라고 한마디로 설명할 수 있겠습니다. 부모 떠난 자식을 다시 부모의 품 안으로 돌아오도록 하려면 어떻게 해야 하는지 한번 살펴 보시죠.
float에 아무런 대응도 하지 않은 상태
#container는 부모 엘리먼트이며 #lnb와 #content는 자식 엘리먼트로서 현재 float된 상태 입니다. 아래 예제는 float에 아무런 대응을 하지 않으면 자식 엘리먼트가 부모 엘리먼트의 높이에 영향을 주지 않는다는 사실을 보여주고 있습니다. #container의 높이가 자식 엘리먼트의 높이를 반영하지 않고 있다는 사실에 주목해 주세요. float에 아무런 대응도 하지 않은 상태의 예제가 준비되어 있습니다.

float에 float으로 대응하는 방법
자식 엘리먼트의 높이를 부모에게 반영하는 방법으로 부모에게도 float 속성을 부여하는 방법이 있습니다. 부모에게 float 속성을 부여하게 되면 부모엘리먼트는 자식 엘리먼트의 높이를 반영합니다. 하지만 부모 엘리먼트의 너비는 float된 두 자식의 너비를 담을만큼만 작게 줄어든다는 사실에 주목해 주세요. 부모의 너비가 브라우저 크기에 따라 가변적이어야 하는 경우에 적용하기 어려운 단점이 있습니다. 또한 조상 엘리먼트들이 겹겹이 존재하는 경우 자식의 높이를 조상 엘리먼트에게 각각 전달하기 위하여 조상 엘리먼트들을 모두 float 시켜야 하므로 일반적으로 사용하는것을 권장하지 않습니다. float에 float으로 대응하는 방법 예제.

float에 overflow 속성으로 대응하는 방법
자식 엘리먼트의 높이를 부모에게 반영하는 방법으로 부모 엘리먼트에 overflow:auto 또는 overflow:hidden 속성을 부여하는 방법이 있습니다. overflow:auto 속성은 자식의 너비가 가변적이고 부모의 너비보다 커지는 상황이 발생할 때 가로 스크롤바를 유발하기 때문에 일반적으로 권장하는 방식이 아닙니다. overflow:hidden 속성은 그러한 상황에서 가로 스크롤바를 유발하지는 않지만 자식의 너비가 넘치는 경우 넘치는 부분이 잘리기 때문에 이 역시 완전하게 안전한 방법은 아닙니다. float에 overflow 속성으로 대응하는 방법 예제.

float을 빈 엘리먼트로 clear 하는 방법
이 방법은 #container 영역이 끝나기 직전 빈 엘리먼트를 넣고 빈 엘리먼트에 clear:both 속성을 부여하여 부모가 자식의 높이를 인식하도록 하는 방법입니다. 하지만 의미 없는 빈 엘리먼트를 사용하기 때문에 이 역시 권장되는 방법은 아닙니다. float을 빈 엘리먼트로 clear 하는 방법 예제. 예제에서는 .clear 라는 빈 엘리먼트를 가시적으로 보이도록 하였지만 실무에서는 보통 .clear {clear:both; height:0; overflow:hidden;} 처리하여 .clear 라는 빈 엘리먼트가 스스로 높이를 갖지 않도록 하고 보이지 않도록 처리 합니다.

float을 가상 선택자 :after로 clear 하는 방법
가장 탁월하다고 생각하는 방법 입니다. 우선 ‘가상 선택자‘라는 개념을 이해하셔야 하기 때문에 약간 상세히 설명드리겠습니다. 여러분들이 익히 알고 계시는 :link, :visited, :hover, :active, :focus는 모두 가상 선택자 입니다. ‘가상 선택자’는 다시 ‘가상 클래스‘와 ‘가상 엘리먼트‘로 구분할 수 있는데요. ‘가상 클래스‘는 특정 엘리먼트에 대하여 아무런 class를 부여하지 않았지만 마치 역동적으로 class를 변경한것과 같은 효과를 낼 수 있는 것들로서 이미 존재하는 엘리먼트에 조합해서 사용할 수 있습니다. :link, :visited, :hover, :active, :focus, :first-child가 가상 클래스에 해당됩니다. 한편 ‘가상 엘리먼트‘란, 존재하지 않는 엘리먼트를 가상으로 생성해내는 선택자로서 :first-line, :first-letter, :before, :after가 있습니다. 심지어 :before와 :after는 HTML문서상에 존재하지 않는 콘텐츠를 출력시키기도 합니다. Hello World Collection이라는 웹 사이트에 신현석님이 ‘Hello World’라는 메시지를 어떻게 출력했는지 살펴보시면 재미있고 이해하기도 쉽죠. 이렇게 가상의 엘리먼트를 생성 #container:after {content:" "} 시킨 다음 display:block; clear:both 처리를 추가하게 되면 의미 없는 빈 엘리먼트를 사용하지 않으면서도 가상 엘리먼트를 이용하여 깔끔하게 float이 clear됩니다. float을 가상 선택자 :after로 clear 하는 방법 예제.

상기 예제로부터 가상 엘리먼트가 스스로 높이를 갖지 않고 화면에 보이지 않도록 처리 하려면 추가적으로 아래와 같이 높이를 제거하고 visibility 속성을 hidden으로 처리 합니다.
#container:after {content:" "; display:block; clear:both; height:0; visibility:hidden;}
하지만 Internet Explorer는 :before, :after 가상 엘리먼트 선택자를 지원하지 않기 때문에 다음과 같은 Hack이 필요합니다.
#container {*height:1%;} /* IE5.5~7 브라우저 대응 Hack */
#container:after {content:" "; display:block; clear:both; height:0; visibility:hidden;} /* 표준계열 브라우저에 대응하는 float 해제용 가상 엘리먼트의 생성 */
Internet Explorer는 엘리먼트에 높이값을 부여했을 때 min-height 속성을 부여한 것처럼 렌더링하는 특징이 있는데 이때부터 float된 자식의 높이까지 인식하게 되는 버그가 있고 이러한 특성을 이용한 것입니다. Internet Explorer 버그와 관련하여 Wystan님 께서 오류를 지적해 주셨습니다. 정확하게 말해서 #container라는 엘리먼트가 min-height속성을 부여한 것처럼 렌더링 하는 특징은 #container라는 엘리먼트에 height 속성뿐만 아니라 width 속성을 부여하는 경우에도 동일하게 나타납니다. 이것은 IE가 hasLayout이 라는 IE만의 속성을 지니고 있기 때문입니다. 그리고 min-height속성을 부여한 것처럼 렌더링 하는 특징은 IE6 이하 브라우저와 IE7이 조금 다릅니다. #container의 부모 엘리먼트에 높이값이 지정되어 있지 않은경우라면 IE6과 IE7은 min-height 속성을 부여한 것처럼 동일하게 렌더링 하지만 #container의 부모 엘리먼트에 높이값이 지정되어 있는 경우라면 IE7은 min-height 속성을 부여한 것처럼 렌더링 하지 않습니다. 따라서 이 팁은 #container의 부모 엘리먼트에 height값이 명시되어 있는 경우 IE7에서 원하는 형태로 렌더링 하지 않으므로 상황에 맞게 제한적으로 사용하여야 합니다. Wystan님께 감사드립니다.^^
참조
- Cascading Style Sheets, level 2 CSS2 Specification - http://www.w3.org/TR/REC-CSS2/
- CSS2 규격 한글 번역문 - http://trio.co.kr/webrefer/css2/cover.html
- YAML > How Floats Work - http://www.yaml.de/en/documentation/basics/how-floats-work.html
- 신현석 > CSS Floating and Clearing - http://hyeonseok.com/soojung/web/2005/03/07/123.html
말로 설명만 했었는데, 깔끔하게 정리되어서 동료들에게 보여주면 되겠네요.
^^
성민장군님, 좋은아침입니다 ^^
이눔 포스팅 시간이 ‘2008년 5월 27일, 6:59′ 인 것 보니 아직도 밤샘 즐겨 하는구나…
집에 좀 들어가라~~~~
별별~ 밤새 글썼다. 지금은 어느별에서 뭣하고 있는고~ ㅎㅎㅎ
정말 필요했던 노하우입니다~ 감사합니다..
늘 좋은정보 혼자 가져가 버리네여..
정리된 설명 잘 읽었습니다. 안그래도 정리가 잘 안되고 있었는데, 좋은 정보 얻어갑니다.
전 언제나 overflow 로 처리 했는데 맨 마지막 방법이 있었군요! 좋은 글 고맙습니다. :D
좋은 글 올려주셔서 고맙습니다. ^^
IE가 가상 엘리먼트를 제대로만 처리하면 참 좋을텐데 이상과 현실은 참 머네요~ ^^;
그런데 IE의 height: 1% hack 설명에 조금 의아한 부분이 있습니다.
관련해서 메일 드렸으니 확인 부탁드려요~
좋은 정보 감사합니다.
음, 마지막 방법이 가장 좋은 방법같지만,
ie6와 ie7에 대한 코드를 또 만들어 주어야 한다는것이 조금 걸리네요.
ie때문에 정말 이래저래 골치가 아프군요.
Wystan님, 감사합니다. 어제 저녁에 너무 바빠서 오늘 아침에서야 수정 하였습니다. (__) 좋은 하루 보내시구요 ^^
좋은글이라 담아갈게용
좋은 내용 감사합니다. 블로그에 출처 명시하고 퍼가도 될까요?
네, 물론입니다 ^^ 이 저작물은 크리에이티브 커먼즈의 2.0 라이센스(저작자표시, 비영리, 변경금지)에 따라 이용하실 수 있습니다. http://creativecommons.org/licenses/by-nc-nd/2.0/kr/ 좋은하루 되세요!
감사합니다.
플로트 때문에 골치아팠던 적이 한두번이 아니었는데 ^^
제 스프링노트로 출처 표시하고 퍼갔어요, 공부하려고..^^
저도 이문제에 대해서 많이 고심 해보았습니다
현재는 빈 엘리먼트를 이용 하는 방법을 사용중입니다
망할! 익스플로러 구버전에서도 적당히 잘 보여주니까요 :D
NL님, nuzl님 안녕하세요? 아무쪼록 골치아픈 문제를 이제는 벗어나셨길 바랍니다. float이 아니고도 IE에서 골치 아플일이 무지하게 많잖아요 ㅜㅜ; 저는 아마 죽어서 묘비에 이렇게 새길껍니다. ‘내가 일찍 죽은건 IE 다 네 탓이다!’ 라구요.
대단하십니다
강진현님, 안녕하세요 ^^; 아니 뭐가 대단하다는건지요 ㅜㅜ;
overflow:hidden을 부모엘리먼트에 줘서 float를 해제하는 방법은 IE에서는 overflow 속성이 엘리먼트에 hasLayout을 부여하기 때문에 가능한 방법이죠.
가끔 가다가 디자인 때문에 overflow:hidden을 적용하지 못하는 엄한 상황이 생기기도 하는데 저는 그때 overflow대신 _zoom:1; 을 줘서 해결하기도 합니다.
아, 그런 방법도 있군요 ^^ 감사해요~
消除浮动元素对浏览器的支持
{overflow:hidden; zoom:1;}、{display:table; width:100%;}、{overflow:hidden; height:1%;}
http://blog.gulu77.com/?p=24
네, IE에서 float을 clear시키는 방법으로 *height:1% 외에도 위와 같은 다양한 방법(zoom, width)이 있다고 설명해 주신것 같네요 ^^
Thank you!
한방에 이해했습니다. 저도 저렇게 정리잘~~ 하는 능력 좀 있었으면 좋겠습니다. ^^
덕분에… 감사합니다 *^^*
질문있습니다. ^^;
float:right를 가진 부분과
float:left를 가진 부분이 있습니다.
다른 로 쌓여 있지 않는 상태에서
바로 밑에 clear:both를 사용안하고 해제 할 수 있는 방법은 없나여?
배혜진님, 감사합니다 ^^
김도훈님, clear:both 속성을 사용하지 않아야 하는 상황이 궁금합니다. 혹시 예제 페이지나 코드로 보여주실 수 있을까요? 이곳 댓글 입력창에서는 HTML 코드를 입력하셔도 코드가 그대로 출력되지 않기 때문에 꺽쇠 대신 다른 기호를 사용하시거나 예제를 보여주시는게 제가 이해하기 빠를 것 같습니다.
[div class="float_right"] A contents [/div]
[div class="float_left"] B contents [/div]
바로 밑에
[div] C contents [/div]
이럴경우 C contents가 위로 올라오는 경우가 있는데 현재 float해제 방법은 둘러쌓고 있는 박스가 있어야만 적용이 되는것 같아서여…
이렇게 박스가 존재하지 않으면서 양쪽으로 float를 사용할 경우 밑에 적용되는 내용에 float이 적용안되게 할 수는 없나여? clear:both를 사용안하고 할 경우…
정말 많은 공부가 되고 있습니다. 이렇게 좋은 사이트가 있다는걸 진작 알았어야 했는데요..
웹눈님 블로그도 충분히 멋지신데요 ^^ 감사합니다.
김도훈님, 댓글을 엄청 늦게 드려서 죄송하네요. 깜빡했습니다. ㅜㅜ; C contents 에 clear:both 를 부여하면 간단하게 해결되는 문제라고 생각했는데요. 혹시 C contents 에도 clear:both 속성을 사용하면 안되는 이유가 있을까요?
^^ 네
그런데 밑에 있는 컨텐츠에 margin-top을 줄 경우 적용이 안되는 것 같아서여
그래서 중간에 clear:both;를 사용했는데….
마진을 적용시킬 수 있는건가여?
김도훈님께, 다시는 안오실줄 알았습니다 ㅜㅜ; 각설하고 제가 테스트해본 결과를 말씀드리자면 float 된 박스 아래쪽에 있는 ‘C’의 margin-top 은 작용하지 않는것이 맞는 것(표준 렌더링) 같습니다. OP, SF, FF 모두 작용하지 않았지만 IE에서만 작용이 되더라구요. 왜 작용하지 않는것이 표준인지에 대해서는 신빙성 있는 설명을 찾지 못했고 표준계열 브라우저들이 렌더링 하는 방식에 따라 추측했을 뿐입니다. 아무래도 float 된 박스와 float 되지 않은 박스이기 때문(서로 다른 층에 떠있는 이유)인것 같구요. 해결 방법은 두 가지가 있네요.
첫째는 A, B 상자에 동일한 margin-bottom 을 부여하는 것.
둘째는 C 상자에 margin-top을 부여하고 float:left; clear:both 하는 것.
김도훈님께 답변 드리려고 다시한번 margin 스펙을 뒤적거렸는데요. 이것과 직접적인 관계는 없지만 찾아낸걸 추가로 말씀드리면 다음과 같습니다. margin-top, margin-bottom 을 통털어 수직 마진이라고 하지요. 근데 이 수직 마진은 수평마진과 다르게 작용하는 점이 있어서 정리해 봅니다.
첫째, 형제끼리 또는 삼촌간의 수직 마진은 통합된다.
형 또는 삼촌에게 margin-bottom:1em, 아우 또는 조카에게 margin-top:1em 을 적용한 경우 두 마진의 합이 2em 이므로 2em 의 마진이 발생할 것 같지만 그렇지 않고 이 둘은 통합되어 1em 의 마진만 표현된다 라는 점 입니다. 만약 두 마진 가운데 큰 값이 있으면 작은 값의 마진은 적용되지 않습니다. 양수끼리 만나면 더 큰 양수가 적용되고 음수끼리 만나면 더 큰 음수만 적용이 되며 양수와 음수가 함께 만나면 두 값을 더한 값이 마진이 됩니다. 이 부분은 4대 브라우저(IE, FF, OP, SF)가 모두 표준대로 렌더링 합니다. 삼촌이란 부모의 형제를 말합니다.
둘째, 수직 마진은 부모 자식간에는 소용없다.
부모 상자로부터 이격시키기 위하여 자식 상자에 수직 마진을 부여하는 경우 부모 자식간 마진은 작용하지 않고 형제 또는 삼촌(부모의 형제)에게만 작용합니다. FF, OP, SF 모두 동일하게 이와 같이 렌더링 하는데 IE만 유독 부모 자식간 수직 마진이 작용하고 삼촌에게는 마진이 작용하지 않았습니다. 이와 관련된 스펙에 대하여 찾아보려 했지만 못찾겠더라구요. 이와 관련된 설명을 찾으면 float 된 위쪽 상자에 수직 마진이 작용하지 않는 원리도 이해할 수 있으리라 봅니다. 혹시 누구라도 찾으시면 댓글 부탁드립니다.
감사합니다. ^^ 흐흐
height:1%;이건 피카푸 버그를 우회할때 유용 합니다.
IE7 인 지금도 피카푸 버그 때문에 냐먼애ㅑㅓㅗㅁ냐어ㅐㅑㅁㄴㅇ
form 을 이쁘게 만들려고 할때 피카푸 버그가 보입니다.
그래서 그냥 테이블로 떼우거나…-_-;
윈도 버전 IE7 불여시3.01 오페라로 테스트 해본 결과
그냥 적당히 완전히 빗나갈 정도만 아니라면 그냥코딩 할수 밖에 없다는 결론을 내렸습니다.
PS: 제가 코멘트 단후에도 코멘트 많이 올라와있네요 float 문제는 여전히 너무 끔찍 합니다 ㅜㅜ
nuzl님, 안녕하세요? form은 보통 th, td 로 마크업되는 구조 아닌가요? ^^ 물론 dt, dd 로 하는 방법도 있겠지만 그런 경우라면 table도 부적절하다고는 생각하지 않습니다.
*heigh:1%; 가 유용한 Hack임은 틀림 없는데 부모의 높이가 지정되어 있지 않을 때에만 사용해야 해서 다소 조심스럽긴 하네요. ^^ 좋은 하루 되세요.
와-정말좋은정보입니다 ^^
float과 clear.. 사실상 우리나라에서는 인터넷 익스플로러가 독점하고 있는 상황이라 -
그다지 신경쓰지 않고, 레이아웃을 설정했더니,
구글 크롬에서 엉망으로 나오더군요. ㅜㅜ
인터넷 익스플로러 8.0에서는 사용해보니 어느정도 크롬과 거의 대등한 표준화를 준수하는거 같더군요 ^ ^
아무튼 좋은 정보 감사합니다. :)