날나리 강좌. ㅋ 레이아웃 짜기, 열(column) 그리고 clear (부록포함) > 퍼블리셔팁

퍼블리셔팁

퍼블리싱과 관련된 유용한 정보를 공유하세요.
질문은 상단의 QA에서 해주시기 바랍니다.

날나리 강좌. ㅋ 레이아웃 짜기, 열(column) 그리고 clear (부록포함) 정보

HTML 날나리 강좌. ㅋ 레이아웃 짜기, 열(column) 그리고 clear (부록포함)

본문

김군 왈, "모했어? 요즘 안보이네... "

A군 왈, "그냥 들락거리긴 했는데.. 병원 갔다오고 약이.. 거의 먹으면 만취상태네. 바닥이 올라오고.. 정신이 온전할 때가 하루 몇시간 안되는 것 같다. "

김군 왈, "온전할 때도 있는감? ㅎㅎ"

A군 왈, "나.. 갈래... "

김군 왈, "지난 번 float 복습을 해보면. 일단 위치하는 것은 img에서 align 만지는 것을 생각하면 되고... 다시 말해 다음은 모두 같네...

<img src="어쩌구" align="left" />
<img src="어쩌구" style="float:left" />
<img src="어쩌구" style="display:block;float:left" />
<img src="어쩌구" align="right" style="display:block;float:left" /> "

A군 왈, "그럼 한번 이제 열로 짜봐"

김군 왈, "머 어려운게 있겠어... 기달려봐"

<!doctype html>
<head><!-- 어쩌구 저쩌구--></head>
<body>
    <div style="width:960px;margin:0 auto;background:yellow">

        <div style="float:left;width:260px;background:green"> 
            LEFT
        </div>

        <div style="float:left;width:500px;">
            CONTENT
        </div>

        <div style="float:left;width:200px;background:red">
            RIGHT
        </div>

        <div style="clear:both;"></div>
    </div>
</body>
</html> 

A군 왈, "그래 잘 했어. 3열로 만들었구나. 이때 3개의 float된 것들의 width + padding + margin + border들의 좌우를 살펴 이들의 총합이 960px 되어야 딱 맞겠지. 위와 처럼 width만 있으면 편하겠지만, padding 등을 설정할려면 그만큼 빼주면 된다우. 이제는 어렵지 않게 잘 계산할테니 문제가 없을 것 같고.. 

또한 float된 요소의 margin도 이때 부모의 margin이나 자식 요소와의 margin이 병합되지 않으니 계산하는데 문제도 없을테이고... 

마지막 clear:both된 블록부터 부모 div는 content의 height를 계산하고 이제 참여된다고 지난번에 이야기 했지...."

김군 왈, "흐음..... 끄으으으으응... 끄으으으응.. 흠..."

A군 왈, " 아니 왜 똥싸고 있어? "

김군 왈, " ㅡ.,ㅡ 저거 내부 마지막에 있는 div의 clear:both 꼭 넣어야 해?"

A군 왈, "헉.....(김군이  눈치를 챘나?  ㄷㄷㄷ )눈치 9단 김군.. 덜덜덜.. 튀어라... "

김군 왈, " 저거 이상하잖아.  처리되는 원리는 이해해.. 그렇다고 의미없는 블록 요소 하나 더 넣는 것은 내 이성에 합당하지 않아. ㅋㅋ 앞서 align은 deprecated이며 스타일 관련된 내용은 이제 HTML 문서에서 보고 싶지 않는 것이 좋다고 했잖아.

근데 이건 style 관련 부분인데 html 요소의 속성 정도가 아니라, 쓰지 않는 새로운 요소를 넣어 버렸잖아. 고로 이것은 나의 이성에 부합하지 않아... ㅋㅋㅋ"

A군 왈, "아이고 알았다.. 알었어. 일단은 지난번에 자세히 말하지 못했지만 float와 clear의 특성을 잘 알면 답이 나오는 것이 있고, 이와는 별론으로 처리하는 또다른 방법이 있지비.

일단은 전자의 방법은 float된 블록을 감싼 부모를 다시 float시키고 폭을 해당 블록내에 꽉채우는 방법이야. 다음과 같은 예제로 보자고..

<div>
    <div style="width:200px;float:left;"></div>
    <div style="clear:both"></div>
</div>

위와 같은 것이 있다면 부모 div의 width를 알 수 있거나 100%로 주면 더이상 아래의 것들이 옆으로 들어와 넘어오지 않고 혼자 블록인 마냥 모두 자리 차지하겠지. 그래서 clear:both 없이도 알아서 꽉채우고 말이야. 이를 적용하면 다음과 같어.

<div style="float:left;width:100%;background:yellow">
    <div style="width:200px;float:left;background:green"> inner float </div>
</div>

부모도 자신을 float시키고 해당 영역의 width를 모두 채우는 값으로 설정하게 된다면, 이 부모 옆에 오는 것이 없기에 보통의 블록 성질을 가진듯 존재하게 되어. 다음에 이어오는 요소들이 옆에 오거나 할 자리가 사실 없기에 영향을 주지 않지.

그런데 제약이 있어. 일단 앞서 보았던 처음 예제에서 부모 960px div를 float시키면 왼쪽이나 오른쪽에 붙고 폭을 100%나 960px인데 이런 것을 모두 구현되지 않겠지. 해결하기 위해서는 다시 div로 한번 감싸면 되는 불편함이 생기고...

또다른 문제는 명시적으로 clear가 되지 않기에 다음에 따라 오는 것들이 옆에 올라와 붙지는 못하겠지만 여전히 영향을 준다는 점이야. 

<div style="float:left;width:100%;background:yellow">
    <div style="width:200px;float:left;background:green">inner-float</div>
</div>
<div style="padding:20px;border:1px solid #f00;">가나다라마바사아자차카타파하</div>

위와 같이 다른 block 요소가 뒤따라 왔다고 해. 처음 div요소가 비록 100% width를 가지고 있긴 하지만, 여전히 float 속성인 탓에 다음에 따라오는 content가 영향을 받어. 여기서 나중에 오게된 "가나다..." 블록의 padding이 어떻게 작동되는지 예측이 가능할까? (일단 IE7이하의 처리는 다르기에 나중에 살펴보자 : IE7이하에서는 width설정이 hasLayoyt 프로퍼티 값을 갖게함)

위의 예제에서 "inner-float"블록의  line-height내지 font-size가 20px보다 크면 "가나다..."가 있는 블록의 padding이 무시해. 이것은 앞서 살펴보았던 float 속성의 특징이야. 레이아웃짜는데는 필요하지 않을 내용이라 보다 자세히 말하지 않았는데, 지금  좀더 알아두면 되겠지.

뒤이어 나온 "가나다..." 블록은 이전 float된 블록을 염두하려 않지만 다만 내부의 content인 "가나다"가 겹치지 않도록 적당하게 위치하게 된다. 

따라서 다시 float:left를 하고 적당한 width를 주어 꽉 채우는 방법도 있지만, 좋지 않은 결과를 발생시킬 수가 있어.

이에 다른 방법으로는 overflow의 변경이야. 이러한 float은 부모의 height 계산에 영향을 주지 않고 붕붕 떠다디는데 이것은 overflow가 visible인 경우에서만 가능해. overflow의 초기값은 visible이니 이것을 다른 값으로 바꾸면 되는데, scroll이나 hidden 및 auto 가 있겠지만, 보통 hidden으로 사용해. 그렇다면 clear:both 블록 없이는 부모에게 overflow:hidden을 사용하면 되겠지. 

<div style="background:yellow;overflow:hidden">
    <div style="width:200px;float:left;background:green">inner-float</div>
</div>
<div style="padding:20px;border:1px solid #f00;">가나다라마바사아자차카타파하</div>


[hasLayOut 프로퍼티]

자.. 그러나 이것은 IE7이하에서 적용되지 않아. 이를 해결해보자. IE는 이러한 것에 관해 독특하게 처리하고 있어 이에 관한 다른 해결방법을 있는데, 보통 이것을 hasLayout 이란 주제로 설명하고 있어. hasLayout이란 IE에서 문서를 렌더링하면서 내부적으로 처리하는 프로퍼티 중에 하나인데, 지금과 같은 경우가 해당 값이 없어서 발생하는 것이기도 한 것이야. 이를 해결하기 위해서는 몇가지 다른 프로퍼티를 변경하면 돼.

이것에 관해서 아마 과거 IE6의 filter 일부를 만져보았다면 미리 경험해볼 수도 있고, 찾다 보면 MSDN 같은 곳에서는 간단히 width나 height만을 주어도 해결이 된다는 이야기 같은 것을 우연히 볼 수도 있을테고...

hasLayout 관점에서 보면 이것에 값을 주는 프로퍼티는 앞서 보았듯이 overflow외에 몇 개가 있어. overflow는 IE7이상에서만 적용이 돼. 또한 직접 height를 넣으면서 해결할 수 있으나 height 사용은 동적으로 내부 content의 height가 바뀌면 예측하기가 어렵겠지? 또한 width는 100% 사용 방법도 생각할 수 있긴 한데, 이것도 다소 우려가 있지.. 그러하기에 또 다른 것으로 살펴 볼만한 것이 zoom이야. zoom은 IE7이하에서 쓸만해. ( 다른 방법으로 앞서 우리는 IE6의 height가 min-height 처럼 처리한다는 점을 알았기에, IE6 전용인 CSS 핵을 써서 _height: 1px로 해결할 수도 있다.)

개인적으로 살펴본 봐, width와 height 사용은 정확히 예측하고 처리가 가능한다면 문제가 없겠지만 다른 잠재된 문제를 만들어 낼 수 있기에, 나의 결론은 zoom을 같이 사용하면 돼. overflow는 IE7이상에서 적용이고 zoom은 IE7이하로 중복이긴 하나 IE6을 해결하기 위해 같이 사용하면 되겠지. 

<div style="background:yellow;overflow:hidden;zoom:1">
    <div style="width:200px;float:left;background:green">inner-float</div>
</div>
<div style="padding:20px;border:1px solid #f00;">가나다라마바사아자차카타파하</div>

자 이제. 완성되었어. 이제 clear:both 없이도 해결되었지?"

김군 왈, "와... 이거 좀 복잡하긴 하다. 외워서 써먹을 수 있긴 하지만 대충 원리는 알 수 있을 것 같다. 이제 그렇다면 이를 넣어서, clear:both 블록을 없애고 다시 한번 짜봐야지."

<!doctype html>
<head><!-- 어쩌구 저쩌구--></head>
<body>
    <div style="width:960px;margin:0 auto;background:yellow;overflow:hidden;zoom:1">

        <div style="float:left;width:260px;background:green"> 
            LEFT
        </div>

        <div style="float:left;width:500px;">
            CONTENT
        </div>

        <div style="float:left;width:200px;background:red">
            RIGHT
        </div>
    
    </div>

    <!-- clear both 대체 체크용 블록 -->

    <div style="padding:20px;margin:20px;border:1px solid #000"> 테스트 블록 </div>

</body>
</html> 

※ 요약,  div의 clear:both 사용 대신 부모의 프로퍼티 추가 내용
  • overflow:hidden; zoom:1
  • 또는, overflow:hidden; _heigth: 1px

---- 추가 부록 : IE6 이하에서 발생 가능한 문제점 처리  ---

이전에 마진은 종종 padding으로 처리하고 내부에서 다시 div를 사용하는 것이 좋다며 가볍게 넘어갔다. 아무래도 후한(?)을 생각해서 발생할 문제와 그에 대한 해결을 다음과 같이 살펴 보자. :) 


[IE6에서 float된 요소의 마진에 대한 버그]

IE6에서는 float된 요소에 마진 사용은 2개의 버그가 있어 꽤나 주의를 요하나 이들은 다행스럽게 큰 조작(?, 가령 스크립트 사용) 없이 해결이 가능하다. 

하나는 비록 clear 프로퍼티를 both 등의 값으로 적절히 사용하였어도, IE6에서 float된 요소에서 margin 사용은 부모의 폭이 이들을 모두 담지 못하게 되면서 문제가 발생하기 시작한다. 그 결과는 다음과 같다. (편의상 부모의 width는 초기값인 auto로 놓고 직접 해당 값을 설정하기보다 다소 무식하게 표시 창의 크기를 변경하며 실험을 하였다. 내부 float된 요소는 모두 margin이 10px이다.) 

6677378017_75b84ba748_z.jpg
정상적 처리라면 첫 그림에서는 LEFT C는 아래로 내려와야 한다. 좀더 폭을 줄이다 보면 다음의 그림처럼 아래로 내려온다. 이러한 경우 부모가 이들을 제대로 모두 감싸야 한다. 그러나 LEFT C만 둘러싸고 있다. 

이 문제도 hasLayout과 관련 되어 있다. 따라서 관련 프로퍼티를 적절히 설정해주면 된다. 앞서 했던 것과 마찬가지로 IE6은 해당 부모의 zoom:1 또는 _height: 1px은 사용하면 될 것이다. 그러나 우린 이미 clear:both를 빼면서 zoom:1 등으로 설정했기에 이 문제는 자연스레 해결되었다. 

다른 버그는 "더블 마진 버그"라고 불리는 것이다. IE6은 float된 방향과 같은 방향의 마진을 설정된 경우, 해당 첫 요소는 설정된 마진의 2배 값을 가진 버그가 있다. 이를 좀더 정확히 작성하면 다음과 같은 조건이다.

  • float된 요소이다.
  • 본래 div,p, h1~h6 등 block 속성이었던 요소이다.
  • float된 방향의 값과 같은 방향의 마진이 설정 되어 있다.  
  • 해당 방향의 첫 번째로 등장하는 요소이다.

 앞의 그림을 다시 재활용 해보자. 내부의 요소는  모두 maring:10px로 설정되었다. LEFT A와 LEFT B 요소 사이는  당연히 20px로 떨어지게 된다. 정상적인 처리이다. 그러나 첫 요소인 LEFT A 블록은 이를 둘러싼 부모와의 왼쪽 마진은 얼마가 되어야 하나? 정상적인 처리라면 지금의 20px이 아닌 그 반으로 10px이 되어야 한다. 이 값은 아래와 위로 떨어진 값과 같이 좌측과 벌어져야 한다. 

비록 float된 요소들의 display 값은 자동적으로 block으로 변경되나, 이를 위한 해결 방법은 display: inline을  해당 요소에 추가하면 된다. 이점은 다소 기괴스러운데, 다행히도 이로 인한 타 브라우저도 부작용을 보이지는 않는다. display 속성에 따른 변화보다는 float 자체의 특성이 별개로 사실상 이런 조건에서 inline과 block 처리 구별이 float에서 그리 상관없이 무시될 만한 것일지 모르겠다. (브라우저에 따라 계산된 display 값은 각자 다르다. 여전히 block으로 처리되는 크롬이나 FF가 있고 IE나 오페라는 inline으로 인식된다. 나중에 한번 좀더 살펴 볼 수 있으나.. 기다리지는 마시기를... )  

----- 

다음 시간에 이어.... 

IE6에서 float된 요소에 관한 마진의 문제와 해결을 추가 하였음...
추천
1
  • 복사

댓글 0개

© SIRSOFT
현재 페이지 제일 처음으로