hasLayout 속성과 홀리 핵(Holly hack)

CSS로 이미지 정렬하기에서 소개했던 CSSclear 속성을 이용하는 float 제거(clearing float)와 동일한 효과를 내는 방법은 몇 가지가 더 있습니다.

그 중 하나인 overflow 속성을 이용하는 방법을 설명하기 전에 인터넷 익스플로러(이하 IE)만의 독자적인 속성인 hasLayout에 대해서 먼저 알아보려고 하는데, 이 속성이 HTML 요소들의 레이아웃, 특히 float된 요소가 렌더링되는 방식에 크게 영향을 끼치기 때문입니다.

그러면 hasLayout 속성이란 무엇이고, 어떤 영향을 끼치는지, 그리고 어떤 방식으로 이 속성을 이용해야 하는지를 알아보도록 하겠습니다.

† 이 글은 hasLayout 속성에 관한 정보로 꾸준히 업데이트되고 있는 On having layout이라는 글을 바탕으로 작성했습니다. 따라서 이 글은 동일한 라이센스를 적용해야만 이용할 수 있도록 규정한 원문의 CCL을 따릅니다. 원문은 Holly Bergevin, Ingo Chao, Bruno Fassino, John Gallant, Georg Sørtun, Philippe Wittenbergh가 함께 작성했습니다.

hasLayout 속성이란?

Layout은 각각의 요소가 어떻게 렌더링되고, 다른 요소들과 어떻게 상호작용 하는지를 결정하는 윈도우즈 버전 IE만의 독자적인 개념(concept)입니다. 이 layout이 적용되지 않으면 표준 규격을 따르는 브라우저와는 사뭇 다른 방식으로 각각의 요소들이 렌더링되므로 브라우저 호환성(cross browsing)을 위해서는 그 특성을 이해할 필요가 있습니다.

일부 HTML 요소는 아무런 설정 없이 기본적으로 Layout을 가지며, 일부 CSS 속성이 지정될 경우에는 Layout이 없는 요소도 Layout 속성을 갖게됩니다. 마이크로소프트의 개발자들은 객체 지향 프로그래밍(Object Oriented Programming) 방식에 기초해서 각각의 요소들이 hasLayout이라고 이름붙인 속성을 가질 수 있도록 해야 한다고 결정했는데 이 속성이 true로 설정된 요소만이 앞서 설명한 Layout 개념을 따르게 됩니다.

† 원문에서는 Layout이 개념(concept)을 가르키고, hasLayout은 이 개념의 적용 유무를 결정하는 속성(property)으로 표현되지만, 두 단어가 그렇게 엄격하게 구분된다고 느껴지지는 않습니다. 또한, hasLayout의 속성(property)은 CSS에서 사용되는 일반적인 속성과는 다른 개념이므로 구분을 위해서 스크립트 속성(script property)이라고 정의하고 있습니다. 사용자가 직접 지정할 수 없고 내부적으로만 처리되기 때문입니다. 이 글에서는 LayouthasLayout 두 단어를 혼용해서 사용하는 경우가 있으니 이 점 감안하시길 바랍니다.

hasLayout 속성이 영향을 미치는 경우들

많은 개발자들이 hasLayout과 관련된 문제를 경험합니다. Layout이 특정한 요소와 그 하위 요소들의 렌더링 방식에 예측하기 어려운 영향을 끼치기 때문입니다.

이렇게 Layout 유무에 따라 발생할 수 있는 일반적인 문제점은 다음과 같습니다.

  • 흔히 발생하는 IE의 float 버그
  • 기본 속성(width, height 등)이 표준과 다르게 적용되는 박스
  • 요소와 컨테이너(container) 사이에 마진(margin)이 합쳐지는 현상
  • 리스트(ul, ol 등)를 만들 때 나타나는 다양한 현상들
  • 배경 이미지 위치를 다르게 해석하는 문제
  • 스크립트를 사용할 때 발생하는 브라우저 호환성 문제

† 원문에서는 이 목록을 간단하고(brief) 완성되지 않았다고(incomplete) 표현하고 있습니다. 다시 말해서, 다른 문제들과도 관련이 있다는 얘기입니다.

hasLayout 속성은 어떻게 지정하는가?

Layout 속성은 특이하게도 CSS를 이용해서 직접 지정할 수가 없습니다. 따라서 CSS에서는 Layout이라는 속성 자체가 사용되지 않습니다. 다만 일부 요소들은 기본적으로 Layout을 갖고(hasLayout = true), 특정한 CSS 규칙이 적용될 경우에도 Layout을 가질 수 있습니다.

기본적으로 Layout을 갖는다고 알려진 요소
  • <html>, <body>
  • <table>, <tr>, <th>, <td>
  • <img>
  • <hr>
  • <input>, <button>, <select>, <textarea>, <fieldset>, <legend>
  • <iframe>, <embed>, <object>, <applet>
  • <marquee>
Layout을 갖게 만드는 CSS 속성
  • position: absolute
  • float: left|right
  • display: inline-block
  • width: ‘auto’ 외의 모든 값
  • height: ‘auto’ 외의 모든 값
  • zoom: ‘normal’ 외의 모든 값 (IE 전용)
  • writing-mode: tb-rl (IE 전용)
  • overflow: hidden|scroll|auto (IE7만 적용됨)
  • overflow-x|-y: hidden|scroll|auto (IE7만 적용됨)

† IE7에서는 이밖에도 position: fixed, min-width, max-width, min-height, max-height 등이 Layout을 활성화시킵니다. 또한 IE6 이상의 표준 렌더링 모드(standards-compliance mode)에서는 인라인 요소의 width, height 속성이 무시되므로, 이 속성으로는 Layout을 갖도록 할 수 없습니다. 기타 자세한 정보는 원문인 On having layout을 참고하세요.

Layout 속성을 이용하는 방법

표준을 따르지 않는 Layout 속성 때문에 레이아웃과 관련된 많은 문제점이 발생합니다. 대표적인 예로는 앞서 CSS로 이미지 정렬하기에서 설명한 p 태그에 clear 속성이 다르게 적용되는 것을 들 수 있지요. 또한, 어떤 요소가 IE에서만 보이지 않는 문제도 hasLayout을 적용하면 해결됩니다.

이렇게 IE에서만 발생하는 Layout 문제를 해결하기 위해서 많은 핵(hack)이 고안되었는데 이들의 공통적인 목적은 Layout이 없는 요소가 Layout 속성을 갖게 만드는 것입니다. 따라서 위에 열거한 CSS 속성을 IE에만 적용시키는 것이지요. 그중에서 대표적으로 사용되는 Holly hack에 대해 알아보겠습니다.

Holly hack

2003년에 John Gallant와 Holly Bergevin이 발표한 Holly hack은 다음과 같은 CSS 규칙을 사용합니다.

/* Hides from IE5-mac \*/
* html .buggybox { height: 1%; }
/* End hide from IE5-mac */

이 핵은 Layout이 없는 요소에 height 속성을 주어서 문제를 해결하는 방법인데 IE가 아닌 표준을 따르는 브라우저에서는 height 속성이 문제를 일으킬 수 있으므로 이런 브라우저에게는 적용되지 않도록 하는 것이 이 방법의 핵심입니다.

사실 Holly hack은 두 개의 핵을 동시에 사용하고 있습니다. 먼저 가운데 줄에 있는 코드는 Tan hack으로 알려진 방법으로 CSS의 공용 선택자(universal selector: *)를 이용해서 IE7 표준 모드(standard mode)를 제외한 현재까지의 모든 IE 브라우저에 적용됩니다.

첫 번째와 세 번째 줄은 Layout 속성이 매킨토시 IE(이하 Mac IE)에는 적용되지 않기 때문에 Mac IE에서는 이 세 줄의 CSS 코드를 모두 주석으로 인식하도록 하는 역할을 합니다. Mac IE가 윈도우즈 IE와는 달리 보다 표준에 가까운 방법으로 렌더링을 하기 때문이지요. 이 방법은 Mac hack이나 comment-backslash 핵으로 불리는데 Mac IE가 주석문의 백슬래시(\) 문자 뒤에 있는 내용을 인식하지 못하고 세 번째 줄까지 주석이 이어진 것으로 인식하는 점을 이용합니다.

하지만 이 방법은 IE7 표준 모드(standard mode)에서는 적용되지 않는데 * html 선택자가 아무 것도 선택하지 않기 때문입니다. 또한, IE6의 표준 모드를 제외하면 overflow: hidden 속성과 함께 사용될 경우에 문제를 일으킵니다.

조건에 따른 주석(conditional comment) 이용하기

저는 개인적으로 크로스 브라우징 문제를 해결하기 위해서 핵보다는 조건에 따른 주석문를 주로 사용합니다. HTML 내에 IE에서만 인식되는 주석문을 넣는 방법으로 위의 Holly hack을 대체하려면 다음과 같은 코드를 사용하면 됩니다.

<!--[if lt IE 7]>
<style>
.gainlayout { height: 0; }
</style>
<![endif]-->

<!--[if IE 7]>
<style>
.gainlayout { zoom: 1; }
</style>
<![endif]-->

IE6 이하 버전에서는 Layout을 갖게 만드는 여러가지 CSS 속성 중에서 height 속성을 사용하는 것이 최선의 방법입니다. 물론 다른 CSS 속성과 충돌이 일어날 경우(예: overflow: hidden)에는 예외지만이요. height 속성으로 어떤 값(1%, 1px, 0 등)을 사용하는지 큰 차이는 없습니다. 하지만 일반적으로 많이 사용되는 1% 값은 극히 드문 경우지만 문제를 일으킬 수도 있다고 합니다. 이 문제에 관한 사항은 IE/Win: negative margins, position:relative, hasLayout를 참고하시기 바랍니다.

† IE6 이하 버전에서 height 지정이 최선의 방법인 이유는 IE5 때문입니다. IE5.5 이상의 브라우저에는 zoom 속성 같은 다른 대안이 있지만 IE5는 현실적으로 height가 최선의 방법이라는 설명입니다.

또한, height 속성은 이 속성을 지원하지 않는 인라인 요소에는 사용할 수 없습니다. IE7에서는 더욱 주의해야 하는데 먼저 height 속성 값은 반드시 퍼센트(%) 단위를 써야 하고, 속성이 적용될 요소의 상위 요소(parent element)에 고정적인 높이가 지정되지 않은 경우에만 또 다른 문제를 피할 수 있습니다. 이런 경우에는 display: inline-block이나 zoom: 1 속성을 사용하는 것이 혹시 모를 문제를 예방할 수 있습니다.

zoom 속성은 IE5를 제외한 IE5.5 이상의 모든 IE 브라우저에 적용되어 Layout을 만들고, 심지어 인라인 레벨 요소도 Layout을 갖게 만듭니다. 특별히 알려진 부작용도 없고요. 위의 예처럼 조건에 따른 주석(conditional comment)을 사용하면 CSS 검증(validation)도 문제없이 통과합니다. Mac IE는 conditional comment를 무시하므로 앞서 설명한 Mac hack도 필요하지 않습니다.

따라서 위 주석문은 height 속성이 필요한 IE6 이하 브라우저(특히 IE5)에게는 height0으로 지정하고, height 속성이 문제를 일으킬 수 있는 IE7에는 zoom 속성을 적용시켜서 Layout을 갖게 만듭니다. 또한, 앞으로 발표될 IE 브라우저에서 Layout 속성을 어떻게 처리할 지 모르기 때문에 가급적이면 IE만의 방법인 conditional comment와 zoom 속성을 사용하는 것이 보다 나은 방법이라고 설명하고 있습니다.

마치며

원문은 이 글보다 훨씬 많은 내용을 담고 있습니다. 내용을 요약하는 과정에서 오역이 있을 수도 있다는 점 감안하시길 바래요. 또한, 원문에 링크된 다양한 글은 제목만 봐도 유용한 정보라는 것이 느껴질 정도입니다. IE에서 레이아웃 문제로 어려움을 겪는다면 관련 글들이 큰 도움이 되리라 생각합니다.

제 경험으로는 Layout과 관련된 대부분의 문제가 Holly hack만으로도 간단히 해결되더군요. 그래서 Holly hack에 관한 내용을 중점적으로 다루었습니다. 다음 글에서 Layout 속성과 overflow 속성을 이용해서 float 효과를 제거하는 방법(clearing float)에 대해서 알아보지요.

  1. CSS로 이미지 정렬하기
  2. hasLayout 속성과 홀리 핵(Holly hack)
  3. float을 제거하는 방법(clearing float)

댓글 5개가 달렸습니다. 태그: , , ,

  1. 애틱 | 2007-08-15 17:47

    흠..영어가 되시니까 정말 좋으시겠어요 ^^
    좋은 내용 잘 보고 갑니다 ~ ^^

  2. wystan | 2007-08-15 19:12

    블로그에서 애틱 님 뵈니 무지 반갑네요. ^^

    잘 보셨다 말씀해 주셔서 고맙습니다~

  3. 황규연 | 2009-01-22 01:09

    이것저것 다른부분을 좀더 공부하다보니 hasLayout 속성 이제야 좀 알듯말듯하네요…^^:

  4. wystan | 2009-01-27 02:16

    hasLayout이 미치는 영향이 광범위해서 특정짓기가 어렵습니다. 그래서 경험적으로 인식하는 경우가 더 많은 것 같아요. ^^;

  5. 제이디 | 2013-05-19 23:35

    좋은글 잘 보고 갑니다. 운문에서 아리까리 한 부분을 주석을 보니 더 잘 이해가 됩니다. ^^

댓글이 닫혔습니다.