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으로 대응하는 방법 예제.

float에 float으로 대응하는 방법 예제

float에 overflow 속성으로 대응하는 방법

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

float에 overflow 속성으로 대응하는 방법

float을 빈 엘리먼트로 clear 하는 방법

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

float을 빈 엘리먼트로 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 하는 방법 예제.

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님께 감사드립니다.^^

2008년 11월 14일 내용 추가.

IE 브라우저에서 float을 해제하는 핵으로 { *height:1% } 대신 { *zoom:1 }을 사용하셔도 됩니다. 높이를 지정하는 방법은 IE7에서 부모 엘리먼트에 높이 값이 존재하는 경우 부모의 높이값으로 부터 1%를 계산하기 때문에 다양한 상황에 적용하기 어려운 단점이 있는 반면 zoom 속성을 사용하게 되면 부모의 높이값과 무관하게 float을 해제할 수 있기 때문에 브라우저 호환성 유지를 위한 더 좋은 방법이라고 생각됩니다.

참조

분류: CSS, 웹 디자인, 웹 표준 | 2008년 5월 27일, 6:59 | 정찬명 | |
트랙백URI - http://naradesign.net/wp/2008/05/27/144/trackback/

51개의 댓글이 있습니다.

  1. 성민장군 5월 27th, 2008 at 10:24

    말로 설명만 했었는데, 깔끔하게 정리되어서 동료들에게 보여주면 되겠네요.
    ^^

  2. 정찬명 5월 27th, 2008 at 10:49

    성민장군님, 좋은아침입니다 ^^

  3. 별별 5월 27th, 2008 at 13:40

    이눔 포스팅 시간이 ‘2008년 5월 27일, 6:59′ 인 것 보니 아직도 밤샘 즐겨 하는구나…
    집에 좀 들어가라~~~~

  4. 정찬명 5월 27th, 2008 at 19:47

    별별~ 밤새 글썼다. 지금은 어느별에서 뭣하고 있는고~ ㅎㅎㅎ

  5. 김태경 5월 28th, 2008 at 13:54

    정말 필요했던 노하우입니다~ 감사합니다..
    늘 좋은정보 혼자 가져가 버리네여..

  6. 부니기 5월 28th, 2008 at 15:36

    정리된 설명 잘 읽었습니다. 안그래도 정리가 잘 안되고 있었는데, 좋은 정보 얻어갑니다.

  7. 한날 5월 28th, 2008 at 16:01

    전 언제나 overflow 로 처리 했는데 맨 마지막 방법이 있었군요! 좋은 글 고맙습니다. :D

  8. wystan 5월 29th, 2008 at 18:38

    좋은 글 올려주셔서 고맙습니다. ^^

    IE가 가상 엘리먼트를 제대로만 처리하면 참 좋을텐데 이상과 현실은 참 머네요~ ^^;
    그런데 IE의 height: 1% hack 설명에 조금 의아한 부분이 있습니다.
    관련해서 메일 드렸으니 확인 부탁드려요~

  9. j 5월 30th, 2008 at 8:59

    좋은 정보 감사합니다.
    음, 마지막 방법이 가장 좋은 방법같지만,
    ie6와 ie7에 대한 코드를 또 만들어 주어야 한다는것이 조금 걸리네요.
    ie때문에 정말 이래저래 골치가 아프군요.

  10. 정찬명 5월 30th, 2008 at 11:13

    Wystan님, 감사합니다. 어제 저녁에 너무 바빠서 오늘 아침에서야 수정 하였습니다. (__) 좋은 하루 보내시구요 ^^

  11. 삽지리 5월 30th, 2008 at 15:09

    좋은글이라 담아갈게용

  12. 파사파사 5월 30th, 2008 at 21:14

    좋은 내용 감사합니다. 블로그에 출처 명시하고 퍼가도 될까요?

  13. 정찬명 5월 31st, 2008 at 4:25

    네, 물론입니다 ^^ 이 저작물은 크리에이티브 커먼즈의 2.0 라이센스(저작자표시, 비영리, 변경금지)에 따라 이용하실 수 있습니다. http://creativecommons.org/licenses/by-nc-nd/2.0/kr/ 좋은하루 되세요!

  14. LN 6월 4th, 2008 at 10:48

    감사합니다.
    플로트 때문에 골치아팠던 적이 한두번이 아니었는데 ^^
    제 스프링노트로 출처 표시하고 퍼갔어요, 공부하려고..^^

  15. nuzl 6월 5th, 2008 at 0:37

    저도 이문제에 대해서 많이 고심 해보았습니다
    현재는 빈 엘리먼트를 이용 하는 방법을 사용중입니다
    망할! 익스플로러 구버전에서도 적당히 잘 보여주니까요 :D

  16. 정찬명 6월 5th, 2008 at 0:58

    NL님, nuzl님 안녕하세요? 아무쪼록 골치아픈 문제를 이제는 벗어나셨길 바랍니다. float이 아니고도 IE에서 골치 아플일이 무지하게 많잖아요 ㅜㅜ; 저는 아마 죽어서 묘비에 이렇게 새길껍니다. ‘내가 일찍 죽은건 IE 다 네 탓이다!’ 라구요.

  17. 강진현 6월 17th, 2008 at 10:53

    대단하십니다

  18. 정찬명 6월 18th, 2008 at 10:03

    강진현님, 안녕하세요 ^^; 아니 뭐가 대단하다는건지요 ㅜㅜ;

  19. 아마티 6월 19th, 2008 at 16:18

    overflow:hidden을 부모엘리먼트에 줘서 float를 해제하는 방법은 IE에서는 overflow 속성이 엘리먼트에 hasLayout을 부여하기 때문에 가능한 방법이죠.
    가끔 가다가 디자인 때문에 overflow:hidden을 적용하지 못하는 엄한 상황이 생기기도 하는데 저는 그때 overflow대신 _zoom:1; 을 줘서 해결하기도 합니다.

  20. 정찬명 6월 19th, 2008 at 23:24

    아, 그런 방법도 있군요 ^^ 감사해요~

  21. seven 7월 29th, 2008 at 23:52

    消除浮动元素对浏览器的支持
    {overflow:hidden; zoom:1;}、{display:table; width:100%;}、{overflow:hidden; height:1%;}
    http://blog.gulu77.com/?p=24

  22. 정찬명 7월 30th, 2008 at 0:08

    네, IE에서 float을 clear시키는 방법으로 *height:1% 외에도 위와 같은 다양한 방법(zoom, width)이 있다고 설명해 주신것 같네요 ^^
    Thank you!

  23. 배혜진 8월 14th, 2008 at 16:47

    한방에 이해했습니다. 저도 저렇게 정리잘~~ 하는 능력 좀 있었으면 좋겠습니다. ^^
    덕분에… 감사합니다 *^^*

  24. 김도훈 8월 14th, 2008 at 17:53

    질문있습니다. ^^;
    float:right를 가진 부분과
    float:left를 가진 부분이 있습니다.
    다른 로 쌓여 있지 않는 상태에서
    바로 밑에 clear:both를 사용안하고 해제 할 수 있는 방법은 없나여?

  25. 정찬명 8월 15th, 2008 at 4:44

    배혜진님, 감사합니다 ^^

  26. 정찬명 8월 15th, 2008 at 4:47

    김도훈님, clear:both 속성을 사용하지 않아야 하는 상황이 궁금합니다. 혹시 예제 페이지나 코드로 보여주실 수 있을까요? 이곳 댓글 입력창에서는 HTML 코드를 입력하셔도 코드가 그대로 출력되지 않기 때문에 꺽쇠 대신 다른 기호를 사용하시거나 예제를 보여주시는게 제가 이해하기 빠를 것 같습니다.

  27. 김도훈 8월 16th, 2008 at 18:56

    [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를 사용안하고 할 경우…

  28. 웹눈 8월 28th, 2008 at 21:00

    정말 많은 공부가 되고 있습니다. 이렇게 좋은 사이트가 있다는걸 진작 알았어야 했는데요..

  29. 정찬명 8월 29th, 2008 at 20:52

    웹눈님 블로그도 충분히 멋지신데요 ^^ 감사합니다.

  30. 정찬명 8월 29th, 2008 at 20:59

    김도훈님, 댓글을 엄청 늦게 드려서 죄송하네요. 깜빡했습니다. ㅜㅜ; C contents 에 clear:both 를 부여하면 간단하게 해결되는 문제라고 생각했는데요. 혹시 C contents 에도 clear:both 속성을 사용하면 안되는 이유가 있을까요?

  31. 김도훈 8월 30th, 2008 at 14:46

    ^^ 네
    그런데 밑에 있는 컨텐츠에 margin-top을 줄 경우 적용이 안되는 것 같아서여
    그래서 중간에 clear:both;를 사용했는데….
    마진을 적용시킬 수 있는건가여?

  32. 정찬명 9월 1st, 2008 at 21:09

    김도훈님께, 다시는 안오실줄 알았습니다 ㅜㅜ; 각설하고 제가 테스트해본 결과를 말씀드리자면 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 된 위쪽 상자에 수직 마진이 작용하지 않는 원리도 이해할 수 있으리라 봅니다. 혹시 누구라도 찾으시면 댓글 부탁드립니다.

  33. 김도훈 9월 2nd, 2008 at 16:46

    감사합니다. ^^ 흐흐

  34. nuzl 9월 2nd, 2008 at 22:00

    height:1%;
    이건 피카푸 버그를 우회할때 유용 합니다.
    IE7 인 지금도 피카푸 버그 때문에 냐먼애ㅑㅓㅗㅁ냐어ㅐㅑㅁㄴㅇ
    form 을 이쁘게 만들려고 할때 피카푸 버그가 보입니다.
    그래서 그냥 테이블로 떼우거나…-_-;

    윈도 버전 IE7 불여시3.01 오페라로 테스트 해본 결과
    그냥 적당히 완전히 빗나갈 정도만 아니라면 그냥코딩 할수 밖에 없다는 결론을 내렸습니다.

    PS: 제가 코멘트 단후에도 코멘트 많이 올라와있네요 float 문제는 여전히 너무 끔찍 합니다 ㅜㅜ

  35. 정찬명 9월 3rd, 2008 at 1:20

    nuzl님, 안녕하세요? form은 보통 th, td 로 마크업되는 구조 아닌가요? ^^ 물론 dt, dd 로 하는 방법도 있겠지만 그런 경우라면 table도 부적절하다고는 생각하지 않습니다.

    *heigh:1%; 가 유용한 Hack임은 틀림 없는데 부모의 높이가 지정되어 있지 않을 때에만 사용해야 해서 다소 조심스럽긴 하네요. ^^ 좋은 하루 되세요.

  36. designe 9월 18th, 2008 at 15:47

    와-정말좋은정보입니다 ^^
    float과 clear.. 사실상 우리나라에서는 인터넷 익스플로러가 독점하고 있는 상황이라 -
    그다지 신경쓰지 않고, 레이아웃을 설정했더니,
    구글 크롬에서 엉망으로 나오더군요. ㅜㅜ

    인터넷 익스플로러 8.0에서는 사용해보니 어느정도 크롬과 거의 대등한 표준화를 준수하는거 같더군요 ^ ^

    아무튼 좋은 정보 감사합니다. :)

  37. 꼬냉 11월 14th, 2008 at 18:27

    좋은정보 감사해요~ 친구들한테도 주소 슝슝~ 날려보내줬습니당~

  38. 정찬명 11월 14th, 2008 at 19:33

    아넵, 감사합니다. 참고로 IE에 대응 하는 핵 {*height:1%} 를 대신해서 {*zoom:1} 핵을 사용하셔도 됩니다. zoom 속성을 사용하시면 부모 높이가 지정되어 있는지의 여부와 무관하게 float을 해제할 수 있어서 좋더라구요. ^^

  39. 정낙훈 1월 2nd, 2009 at 18:32

    왼쪽 header 영역에 100% 되는 방법 없을까요?
    코드는 아래와 같습니다만..^^; 여기 남겨도 되는지 모르겠네요;

    MyNote

    /* 글로벌 */
    * { margin:0; padding:0; font-size:small; font-family:돋움, Dotum, AppleGothic, sans-serif;}
    html {height:100%;}
    body{background:url(http://eond.com/eond/files/attach/images/120347/900/162/bg_body.gif);height:100%;}
    /* 전체 구조 */
    #wrapper{float:left;background:url(http://eond.com/eond/files/attach/images/120347/900/162/bg_wrapper.gif) right bottom no-repeat fixed;width:100%;height:100%;overflow:auto;}
    #header{float:left;width:52px;height:100%;background-color:#F6F6F6;}
    #container {float:left;width:500px;border:1px solid white;}
    #footer{float:left;width:200px;}
    /* 컨테이너 */

    /* 푸터 */

    1

  40. 정낙훈 1월 2nd, 2009 at 18:33

    아..;; 메일로 보내겠습니다;

  41. 정찬명 1월 2nd, 2009 at 19:06

    앗, 다른 분들도 참고하실 수 있기 때문에 댓글로 써주시면 더 좋습니다. ^^;

  42. 정낙훈 1월 2nd, 2009 at 19:43

    코멘트에는 HTML코드가 가능하지 않도록 하는 것이 더 좋을 것 같기도;;

    [!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"]
    [html]
    [head]
    [title]MyNote[/title]
    [style]
    /* 글로벌 */
    * { margin:0; padding:0; font-size:small; font-family:돋움, Dotum, AppleGothic, sans-serif;}
    html {height:100%;}
    body{background:url(http://eond.com/eond/files/attach/images/120347/900/162/bg_body.gif);height:100%;}
    /* 전체 구조 */
    #wrapper{float:left;background:url(http://eond.com/eond/files/attach/images/120347/900/162/bg_wrapper.gif) right bottom no-repeat fixed;width:100%;height:100%;overflow:auto;}
    #header{float:left;width:52px;height:100%;background-color:#F6F6F6;}
    #container {float:left;width:500px;border:1px solid white;}
    #footer{float:left;width:200px;}
    /* 컨테이너 */

    /* 푸터 */
    [/style]
    [/head]

    [body]
    [div style="clear:both;"][/div]
    [div id="wrapper"]
    [div id="header"]1
    [/div]
    [div id="container"]
    [br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /][br /]
    [/div]
    [div id="footer"]
    [/div]
    [div style="clear:both;"][/div]
    [/div]
    [div style="clear:both;"][/div]
    [/body]
    [/html]

  43. 정찬명 1월 2nd, 2009 at 23:28

    현재 #header의 높이는 100%가 적용되어 있지만 콘텐츠에 따라서 가변적으로 늘어나는 상대적인 높이가 아니라 브라우저의 뷰포트를 기준으로 100%가 잡히게 되는데요. 이렇게 되는 이유는 #header가 부모 엘리먼트를 기준으로 상대적인 높이를 갖게 되는데 부모인 html, body의 높이 100%는 바로 뷰포트의 높이이기 때문에 결국 #header의 높이 100%는 한 화면의 뷰포트 높이보다 더 클 수 없게 됩니다.

    만약 #header가 콘텐츠 영역의 높이에 따라 가변적인 높이를 가져야 하는 상태로 배경을 넣고자 하는 것이라면 이렇게 할 수 있습니다.

    1. 현재 body 요소에 적용된 background는 html 요소에 적용.
    2. 현재 #wrapper에 적용된 background는 body 요소에 적용.
    3. #header에 적용하고자 하는 background는 #wrapper에 적용.

    그러나 만약 #header가 라운딩된 디자인 상자라서 위/아래 추가로 이미지를 적용해야 한다면 이때는 어쩔 수 없이 빈 엘리먼트(span)가 두개 필요하겠지요. 이 때 사용되는 빈 엘리먼트는 #header의 자식이 되어서는 안되고 #header, #container와 형제 관계로 존재해야 합니다. 라운딩 모서리에 필요한 span에는 각각 .hTop .hBottom 이라는 클래스를 부여 합니다.

    #wrapper의 position을 relative로 설정한 다음 .hTop .hBottom의 position은 absolute 상태로 처리하고 .hTop 은 top:0 으로 위치지정 하고 .hBottom은 bottom:0 으로 위치를 지정 합니다. 이렇게 되면 라운딩 된 위/아래 모서리들은 콘텐츠의 높이에 따라서 자신들의 수직 위치는 가변적이 됩니다.

    제가 질문을 제대로 이해하고 답변 했는지 모르겠군요. 이럴때는 왜 #header를 100%로 만드려고 하는지, 그리고 100%라는 표현은 상대적인 값이기 때문에 무엇을 기준으로 100% 인지 설명해 주시면 더 좋을것 같습니다. 부족한게 있으면 다시 질문해 주세요. ^^

    PS : 코드 붙여넣기 불편하시죠? 이럴때는 정낙훈님 웹 계정에 예제 파일 올려주시고 링크 해주시면 더 편하지 않을까요? ^^

  44. 정낙훈 1월 3rd, 2009 at 2:23

    답변 감사합니다. html 요소에까지 배경을 넣는다는 생각은 못했네요.
    하지만 #header의 배경은 단색이라 그냥 background-color 로 처리하려고 그랬거든요.
    되도록이면 이미지는 사용하지 않으려고 했는데, #header의 높이가 뷰포트보다 어쩔 수 없이 더 클 수 없는 상황이라면, 배경그림을 넣는 것이 더 머리 아프지 않게 하는 방법인 것 같습니다. 다음부터는 제 계정에 예제 파일을 올려놓고 링크하도록 하겠습니다. 제가 여기에만 너무 집착한 나머지 그 외에 필요한 부분에 대한 생각은 전혀 하질 못했네요. ^^;

  45. 강짱 1월 7th, 2009 at 21:01

    아 제가 찾던 답변이 여기 있네요.
    제가 지금 레이아웃 짜고 있는데요. 저도
    clear:both;를 했더니 margin-top이 안먹어서 애좀 먹었어요..

    그래서 찬명님 해결 방법으로 해결했더니. 첫번째 방법은 되더군요..

    도훈님이 주신 질문과는 조금 다르지만..
    http://blossomm.mireene.com/margins_clear.html
    이렇게 해봤는데, 두번째 방법은 IE에서는 겹쳐진다는..(아.난감)
    IE에서의 해결 방법은 없을까요??(갑자기 막 궁금해서,,ㅎㅎ)

    이게 왜 이런건지..?제 소스는 margin부분이 겹치지도 않는데 ,,,;;
    collapse margins이라고,계속 찾아봤는데. 아직은 이해하기가 어렵더라구요.
    담엔 collapse margins 대해서 자세하게,,으하하하하하;;;(뻘….쭘;;)

  46. 정찬명 1월 8th, 2009 at 0:58

    강짱님 예제를 봤는데요. #lnb의 float을 빼고 clear:both를 주면 간단하게 원하는 배치가 나오지 않나요? 그런 예제가 이미 페이지에 포함되어 있던데요?

    저 같은 경우는 박스를 2~3단의 컬럼으로 몇개 배치하고 그 컬럼들의 높이를 부모에게 전달해서 아래쪽에 등장하는 박스들을 자연스럽게 밀어내 줄 필요가 있을 때에만 float을 사용하는데요. 예제를 딱 보아하니 저것들은 굳이 float을 사용하지 않아도 될 것 같아요. 저라면 IE 에서 버그 만날 확률이 높기 때문에 float 대신 #gnb는 absolute 처리하고 헤더부분의 높이는 #gnb와 #lnb의 부모 요소에 padding-top을 부여하는 것으로 해결할 것 같습니다.

    마진 병합에 관한 이야기는 다시 한번 설명해 보겠습니다. 아래와 같은 HTML 구조를 먼저 생각해 주세요.

    [부모]
    [난형]…[/난형]
    [난제]…[/난제]
    [/부모]

    [삼촌]…[/삼촌]

    서로간의 관계가 파악이 되셨다면 이제 설명을 들을 준비가 되신겁니다.

    일단 형제, 삼촌, 부모를 통털어 수평 마진은 서로의 마진을 있는 힘껏 밀어내서 절대로 병합되지 않습니다. 수식으로 표현하면

    ‘난형 우측 마진 10px’ + ‘난제 좌측 마진 10px’ = ‘형제간 수평으로 20px 마진 발생’

    과 같이 정상적인 계산 방식으로 마진이 작용합니다.

    그러나 수직 마진은 적은 마진 수치를 가진 녀석이 자신의 마진을 숨겨버립니다.

    ‘난형 아래쪽 마진 20px’ + ‘난제 위쪽 마진 10px’ = ‘형제간 수직으로 20px 마진 발생’

    상식적으로 ‘난형’과 ‘난제’는 수직으로 ‘30px’의 마진이 발생해야 할 것 같지만 마진 수치가 작은 ‘난제’의 마진은 작용하지 않고 ‘난형’ 마진에 병합되어 버려서 고작 ‘20px’의 마진만 발생합니다. 이런일 흔히 있잖아요. 형제간에 한 녀석이 너무 잘나면 다른 녀석이 상대적으로 박탈감 느껴서 탈선하는. ㅜㅜ; 그런데 CSS 에서는 형제뿐만 아니라 ‘삼촌’ 관계에서도 이런 일이 발생한다는. ㅎㅎㅎ.

    결국 수직 마진은 아래와 같이 간단명료하게 정리할 수 있습니다.

    1. 형제 또는 삼촌 관계에서 발생하는 수직 마진은 병합(merge)이 되는데
    2. 양수끼리 만나거나 음수끼리 만날때는 수치가 작은 값은 병합되어 큰 값만 작용하고
    3. 양수와 음수가 만날때는 병합됨 없이 그 두 값을 더한 값이 작용하고
    4. 형제나 삼촌 관계 아닌 부모자식 사이에서는 마진이 작용하지 않는다

    라는 겁니다. 나름 쉽게 다시 한번 쓴다고 고민 했는데 여전히 어려울 수 있겠네요. 누가 이 원리를 잘 설명해줄 예제 팍팍! ㅋㅋㅋ.

  47. 강짱 1월 8th, 2009 at 10:07

    오웃.
    아 저도 absolute로 해결하긴했지만..
    그냥 문득 이런저런 해결방법이 궁금해서요~ㅎㅎ
    저거때문에 일 안하고 괜히 끄적거리고 있었다는.

    ‘그러나 수직 마진은 적은 마진 수치를 가진 녀석이 자신의 마진을 숨겨버립니다.’
    다는 아니지만 이해가 많이 되네요.
    쌩유해요~

  48. 강짱 1월 8th, 2009 at 10:11

    아 저 제 예제에서 첫번째 방법이 IE에서는 되지만..FF에서는 margin-top이
    안먹어서 물어본거였다는…흠..

  49. 정찬명 1월 8th, 2009 at 14:28

    아, 이제서야 강짱님이 궁금해 하던 문제가 무엇이었는지 파악했어요. 사실 이 문제를 이해하기 전까지는 저도 그렇게 작용하는지 몰랐었습니다.

    문제는 float된 ‘난형’과 float되지 않고 clear된 ‘난제’ 사이에서 ‘난형’의 아래쪽 마진은 작용하는데 ‘난제’의 위쪽 마진은 왜 작용하지 않는지 그걸 물어보신 거로군요. 맞죠?

    CSS 명세에서 적당한 설명을 찾기 못했기 때문에 표준계열 브라우저들의 작동박식을 근거로 설명해 보자면 ‘난제’의 위쪽 마진은 현재 ‘난형’에게 작용하지 않고 ‘부모’에게만 작용하고 있습니다.

    표준계열 브라우저들의 작동 방식이 옳다는 전제 아래 남은 숙제는 일단 float된 ‘난형’과 float 안된 ‘난제’ 사이에 발생하는 ‘마진까지 clear 되지 않는 현상’ 이로군요.

    실험을 위해 ‘난형’과 ‘난제’의 마크업 순서를 바꿔 놓아 보면 아래쪽에 놓여 float된 ‘난형’에게 발생하는 위쪽 마진은 ‘난제’에게 작용하지만 원래의 마크업 순서로 다시 돌아와서 ‘난제’에게 위쪽 마진을 설정해 보면 이 마진은 ‘난형’에게 작용하지 않습니다.

    현재로써는 아마도 ‘float된 요소와 float 안된 요소가 서로 다른층에 떠 있고 float 없이 clear된 ‘난제’의 위쪽 마진은 float된 형재에게 작용하지 않는다’ 라는 류의 설명이 CSS 스펙에는 생략되어 있지만 브라우저 벤더들 사이에서 누군가 먼저 이렇게 구현했고 그것을 따라하지는 않았을까 라는 추측 잘못된 추측도 해봅니다.

    결국 현상만 설명이 되었고 원리는 제 깜냥으로는 설명이 안되네요. 원리를 알고 이해하는것이 가장 좋겠지만 말이죠. 아, CSS 너무 어렵네요. ㅎㅎㅎ.

  50. 정찬명 1월 8th, 2009 at 14:54

    조금전 winstan님과 담배를 한대 태우며 자문을 구했더니 이렇게 구현되는 방식이 CSS 명세에 설명되어 있다고 하더군요. 저는 아무리 눈 씻고 찾아봐도 안보이던데 ㅡㅡ;

    원리는 이랬습니다.

    float된 ‘난형’과 float 없이 clear된 ‘난제’가 있을 때 ‘난제’는 ‘난형’의 높이값에 해당하는 margin-top을 자동으로 가지게 된다. 따라서 ‘난제’에 ‘난형’의 높이보다 작은 수치의 위쪽 마진을 설정하면 마치 마진이 적용되지 않은 것 처럼 보이고 ‘난형’의 높이보다 높은 수치의 마진을 적용해야만 비로소 ‘난형’과 멀어지게 되는 겁니다.

    어쨌든 키 포인트는 ‘둘이 서로 다른 층에 떠 있다’는 점이고 새롭게 알게된 사실은 이런 경우에 ‘난제’에게 자동으로 ‘난형’의 높이에 해당하는 margin-top이 발생한다는 사실 이네요.

    관련 속성이 어디에 설명되어 있는지는 wynstan님께서 어느부분인지 알려주신다고 하시니 잠시 후에 다시 뵙겠습니다. ^^

  51. 정찬명 1월 8th, 2009 at 15:48

    float과 clear된 요소의 margin-top 부분에 대하여 여기 설명이 되어 있습니다.
    http://www.w3.org/TR/CSS21/visuren.html#floats

    HTML 구조


    <body>
    <p>Some sample text <img /> that has no other... </p>
    <p>The second paragraph...</p>
    </body>

    CSS 구조


    img { float:left; }
    p { margin:2em; clear:left; }

    설명

    Both paragraphs have set ‘clear: left’, which causes the second paragraph to be “pushed down” to a position below the float — “clearance” is added above its top margin to accomplish this (see the ‘clear’ property).

    두 문단에는 ‘clear:left’가 설정되어 둘째 문단은 float 아래로 떨어진다. clear 처리는 float을 해제하기 위하여 아래쪽에 놓인 상자에 위쪽 마진을 추가한다.

    즉, clear 시키기 위해서 둘째 문단에 가상의(?) 위쪽 마진을 두는데 이 마진은 딱 float된 녀석의 높이 만큼만 발생하기 때문에 둘째 문단보다 margin-top의 수치가 크지 않으면 마치 마진이 사라진 것처럼 보인다는 겁니다.

    이해는 했지만 또 설명하기란 쉽지 않군요. 덕분에 float, clear, margin 공부 새로 했습니다. ㅎㅎㅎ.

댓글 남기기

전송된 글이 나타나지 않는다면 필터링 된 것입니다. dece24앳gmail.com 으로 메일 주세요.
(X)HTML 코드 사용이 가능하지만 코드가 그대로 출력되기를 원하시면 <꺽쇠>는 [괄호]로 변환해 주세요.

필수

필수(공개 안됨)