본문 | 검색 | 글 분류 | 최근 글 | 최근 댓글 | 기타 | 아래로


IE6에서 레이어 고정시키기 핵. Fixed Layer Hack for IE6.

CSS에는 position:fixed 라는 속성이 존재하고 이 속성이 부여된 엘리먼트는 화면에 고정되어 스크롤을 해도 움직이지 않고 항상 같은 자리에 머물게 됩니다. 흔히 "스크롤을 따라다니는 배너" 라고 표현하는 이런 UIO(User Interface Object) 따위를 코딩할 때 이 속성을 사용할 수 있는데 보통의 경우 IE6에서 지원하지 않기 때문에 별도의 자바스크립트를 추가하여 이 기능을 구현해 왔습니다. 하지만 이제는 더이상 그럴 필요가 없을것 같습니다. 자바스크립트는 전혀 사용하지 않고 CSS Hack을 사용하여 IE6 에서 position:fixed 상태의 레이어를 구현할 수 있는 팁을 발견하였습니다.

예제 미리보기
http://naradesign.net/open_content/reference/fixedLayer/index.html

CSS Code

* { margin:0; padding:0;} /* html, body 사이의 간격을 제거 */
html { _overflow:hidden;} /* 기본 스크롤 제거 */
body{ _height:100%; _width:100%; _overflow:auto;} /* 대체 스크롤 생성 */
#content { width:580px; height:1000px; margin:20px; padding:10px; background:#eeeeee;}
#aside { position:fixed; _position:absolute; _z-index:-1; left:650px; top:20px; width:100px; height:300px; padding:10px; background:#dddddd;}

HTML Code

<div id="content">
<h1>Fixed Layer Hack for IE6</h1>
</div>
<div id="aside">
<h2>Example</h2>
</div>

이 팁의 핵심은 <html> 요소에서 발생하는 스크롤을 제거하고 <body> 요소에 스크롤을 부여하는 것입니다. <html> 에 스크롤이 붙으면 <html> 내부의 모든 콘텐트가 스크롤과 함께 움직이지만 <body> 요소로부터 발생한 스크롤은 <html> 요소를 offset(x,y) 기준점으로 삼고있는 #aside 요소의 화면배치에 아무런 영향을 주지 않습니다.

만약 <body> 요소에 position:relative 를 주게 된다면  offset 의 기준점이 <body> 가 되기 때문에 레이어를 화면에 고정할 수 없는 상태로 다시 돌아가게 됩니다. 예제 코드에서 강조 표시된 코드가 관련 코드이며 이 팁의 내용을 더욱 자세하게 이해하고 싶으시면 관련 CSS 속성을 하나씩 제거하면서 테스트 해보시기 바랍니다.

브라우저 호환정보

  • Firefox2, Opera9, Safari2, IE6~7 에서 모두 동일하게 position:fixed 형태로 렌더링 합니다.
  • IE5.0~IE5.5 버전의 브라우저에서는 position:absolute 형태로 렌더링 합니다.
  • DTD가 Quirks Mode 상태일 때에는 적용되지 않습니다.

발견된 문제점

  • 현재 코드는 IE6 핵으로서 #aside 영역에 _z-index:-1 속성을 사용하였기 때문에 IE6 에서는 #aside 영역의 텍스트를 자연스럽게 드래그 하거나 링크를 클릭할 수 없습니다. 다른 브라우저에서는 발생하지 않는 현상입니다.
  • 한편 _z-index:-1 을 제거하게 되면 텍스트를 드래그 하거나 링크를 클릭하는 것이 가능하지만 화면크기를 줄였을 때 #aside 레이어가 세로 스크롤바를 덮는 현상이 발생합니다. 이 문제 역시 IE6 에서만 발생하는 현상입니다.

참조

분류: CSS | 2007년 9월 8일, 5:57 | 정찬명 | |
트랙백URI - http://naradesign.net/wp/2007/09/08/128/trackback/

21개의 댓글이 있습니다.

  1. 김정윤 댓글 | 2007년 9월 8일, 14:25

    브라우저의 기본 스크롤을 컨트롤 하는 방법이라 적용하기가 살짝 두렵네요 ^^;;
    ie6에서 창을 줄였을 경우 세로스크롤에 문제도 조금 있구요(레이어가 스크롤 위로 올라가는… 위치도 살짝 ^^;;)
    소스를 약간만 보완하면 좋은 팁이 될거 같네요~ 좋은 정보 감사요~~~

  2. 정찬명 댓글 | 2007년 9월 8일, 23:01

    아~ 브라우저 크기를 줄였을 때 레이어가 스크롤을 덮어버리는군요. 이거 아직 끝나지 않은 숙제인걸요. 정윤님, 좋은 해결방법이 없을까요?

  3. 정태영 댓글 | 2007년 9월 9일, 2:25

    예전에 이 방식을 보고 적용해서 작업했던 적이 있는데 이런 원리였군요.

    위엣 분이 얘기하신 문제는 저도 겪어봤는데 +_+ 원리를 알면 해결책도 알 수 있는 법!!

    javascript 의 onload, onresize event 에서 viewpoint 사이즈를 얻은 후 body 의 height 를 height(viewpoint)-height(fixed layer) 로 조정해주면 해결이 가능하지 않을까요?

  4. 정찬명 댓글 | 2007년 9월 10일, 13:38

    일단, Javascript 를 사용하지 않고 이 문제를 해결 할 수 있는 방법이 있는지 이 글을 보신 분들과 함께 연구해 보면 좋겠네요. 저도 틈날 때 연구해 보겠습니다. 지금으로서는 딱히 떠오르는 생각이 없지만 ㅡㅡ;

  5. freeism 댓글 | 2007년 9월 11일, 11:14

    와… 이런 방법이 또 있나요?
    별나라 이야기 같습니다만… 언젠가 써먹을일이 있을 때 매우 유용할 듯 싶습니다. ^^
    감사합니다~~

  6. 조준희 댓글 | 2007년 9월 14일, 22:04

    흥미로운 CSS code 네요..^^
    그런데 _position:absolute; 같이 position 앞에 _ 를 붙이는건 어떤 경우인가요? _ 를 붙인걸 몇번인가 본적이 있는데 설명을 찾다가 결국은 여기에 질문을…^^;;;

    그리고 혹시나 해서 하나 더 덧붙입니다.
    IE 6.X 에서만 발생하는 문제인데요(뭐 ie가 항상 문제를 일으키는 관계로 그렇게 놀랍지는 않습니다만..ㅡ..ㅡ )

    CSS 코드는

    * {
    margin:0;
    padding:0;
    }

    #wrap1 {
    float:left;
    width:180px;
    height:300px;
    background-color:#999999;
    }

    #wrap2 {
    margin-left:180px;
    height:600px;
    border-left:1px solid #000000;
    }

    이구요, html은

    [div id="wrap1"]test[/div]
    [div id="wrap2"]test[/div]

    입니다. 문제는 두 div 사이에 2 픽셀의 간격이 생기는데요…왜 마진이 생기는지 설명은 안되지만 나름 발견한 문제여서 글을 남깁니다…
    (정찬명 님께서 올리신 글하고는 크게 상관은 없는 것 같지만 딱히 올릴만한 곳을 찾지 못해서..)

  7. 이은주 댓글 | 2007년 9월 18일, 16:20

    좋은 정보네요.^^
    이런방법도 있구나~하면서 놀랍고 제공해 주셔서 감사합니다. 잘쓰겠습니다.

  8. 정찬명 댓글 | 2007년 9월 18일, 21:50

    조준희님께, 답변이 엄청 늦었네요. 기다리셨다면 죄송합니다 (__)
    정체불명의 3px 마진이군요. 저 버그도 분명 이름이 있을텐데 제가 IE6의 모든 버그들을 외는게 아니라서 ㅡㅡ; 이름은 모르겠구요.

    본래 표준대로 따지자면 float 된 박스와 float 되지 않은 박스는 서로의 공간배치에 영향을 미치지 않고 겹쳐야(다른층에 떠있어야) 정상입니다. IE 이외의 표준계열 브라우저에서 보시면 #wrap1과 #wrap2는 분명 겹쳐 보이실껍니다.

    하지만 겹치치 않기 위해서 #wrap2 에 다시 margin-left:180px 을 주셨네요.

    이 버그는 IE에서만 발생하며 float 된 박스와 float 되지 않은 박스가 만날 때 발생하는 것 같습니다.
    즉, #wrap1과 #wrap2 가 만나는 상황이 지금 딱 그런 상황이라서 이유없는 마진이 발생한 것 같구요.

    저같은 경우 화면을 배치할 때 #wrap1과 #wrap2 모두 float 시켜 버립니다.
    그렇게 되면 margin-left 를 줄 필요도 없고 3px 마진 버그도 없게 됩니다.

    그리고 나서 #wrap1과 #wrap2의 높이를 부모 엘리먼트에게 전달하기 위해서 #container 쯤 될법한 부모상자에 overflow:hidden 을 주면 자식들의 높이값이 부모에게 제대로 전달됩니다.(이 설명이 이해가 되지 않으시면 #wrap1과 #wrap2를 모두 감싸는 #container 상자를 만드신 다음 #container 상자에 배경색을 넣고 overflow:hidden 속성을 넣거나 빼면서 테스트 해보시면 됩니다. overflow:hidden 속성이 없으면 #container 의 높이는 0px이 되거든요.)

    설마 도움이 되시려나요? ^^

  9. 정찬명 댓글 | 2007년 9월 18일, 21:51

    이은주님, 반갑습니다 ^^ 사용시 부작용 꼼꼼하게 읽어보시고 사용해 주세요 (__)

  10. 정찬명 댓글 | 2007년 9월 19일, 3:25

    코드를 약간 수정하였습니다. #aside 레이어가 스크롤을 덮는 문제를 _z-index:-1 으로 해결했습니다. 그러나.. #aside 영역의 텍스트를 드래그 하거나 링크의 클릭이 되지 않습니다. 쉬뜨.. 해결사 어디 없나요? ㅡㅜ; (현재로서는 네비게이션 요소만 아니라면 일단 쓸 수는 있겠네요.)

  11. 기다림hiphapis 댓글 | 2007년 11월 5일, 21:41

    허걱.. 이렇게 좋은 정보를 몰래콤시 올려놓으시다닝~!!
    제 글에 트랙백 달아주세요옹~*
    (제가 달려고 하니, 뭔가 좀 거시기한거 같아서 -ㅛ-;;)

  12. 정찬명 댓글 | 2007년 11월 5일, 23:03

    하하~ 몰래콤시 올려놓은 것은 아니구요~ 요한씨 글에 댓글을 적었는데 어느순간 지워져 있더라구요. 요한씨의 필더링 시스템 때문인지 아니면 제가 글을 적어놓고 전송버튼을 안눌렀던가.. 그랬던 모양이에요. 늦었지만 결혼 축하드리구요. 직접 가서 축하해줬어야 하는데 그러지 못해서 미안했어요. ^^

  13. 기다림hiphapis 댓글 | 2007년 11월 9일, 12:34

    아니에요~, 축하만 해주셔도 감사한걸요~ㅎㅎ

  14. 콩바구니 댓글 | 2008년 2월 21일, 13:27

    동생이 발견한 방법인데요.
    _top:expression(documentElement.scrollTop + (documentElement.scrollTop>120?스크롤뒤의높이 :처음높이-documentElement.scrollTop));

    이렇게 하면 완벽하게 Fixed포지셔닝이 가능해지더군요.

  15. 정찬명 댓글 | 2008년 2월 21일, 13:48

    콩바구니님, 의견 감사합니다. 콩바구니님의 코드가 포함된 예제페이지를 한번 볼 수 있을까요?

  16. 콩바구니 댓글 | 2008년 2월 21일, 13:54

    이크. 여기는 댓글 한번작성하면 수정할수 없나보네요.ㅠㅠ

    _top:expression(documentElement.scrollTop+ 높이);

    _top:expression(documentElement.scrollTop + (documentElement.scrollTop>갑?을:병-documentElement.scrollTop));
    갑: 처음 높이값
    을: 스크롤하는동안의 높이값.
    병: 갑+을

    이게 맞습니다.

    처음방법은. 일반적인 Fixed포지션이고,
    두번째방법은 조금더 발전된방법이랄까요. 스크롤이 내려갈때의 위치를 따로 지정할수 있습니다.

  17. 콩바구니 댓글 | 2008년 2월 21일, 13:57

    제 블로그에 바로 적용했지요.
    적용한 css 파일의 주소는

    http://cfs.tistory.com/custom/blog/2/24447/skin/images/style_ie6.css 입니다.

  18. 정찬명 댓글 | 2008년 2월 21일, 23:10

    아넵, 잘 봤습니다. 그런데 한가지 궁금한건요. expression을 사용했을때 아무런 문제상황이 발생하지 않으리라는 보장이 있나요? 표준이 아니라는 문제를 제외하고 페이지의 성능등에 영향을 미치지 않는지 궁금합니다.

  19. 콩바구니 댓글 | 2008년 2월 22일, 23:05

    expression을 사용했을때 잘못하면 특정상황에서 무한루프에 빠질수 있기때문에 사용을 자제하라는 말이 있더군요. 자세한문제는 잘 모르지만… 제 블로그에 적용해보고 시험해본결과. 한두개의 Fixed포지셔닝에 활용하는정도로 페이지의 로딩이 느려진다거나.CPU점유율이 높아진다거나. 하는 현상은 보이지 않았습니다.

  20. 호이♡ 댓글 | 2008년 3월 23일, 23:02

    이번 프로젝트에 팝업 상단 부분을 고정시키기 위해 이 포스트를 참고하여 적용해봤는데 결정적인 문제가 있더군요… 고정시키려는 부분 외에는 relative나 absolute 포지셔닝을 사용할 수가 없네요 적용하면 그 부분도 역시 고정이 되어버리기 때문에… ^^;

    특별히 포지셔닝을 하는 부분이 없다면 괜찮겠지만 사이드바에 사용하기엔 위에 있던 약간의 문제들도 있고 실무에서 사용하기엔 약간 위험부담이 있을 것 같습니다.(저같은 경우는 팝업컨텐츠가 특별히 포지셔닝을 사용하는 부분이 없어 일단 유지하고 있습니다)

    덧붙여 이번에 안 문제지만 IE7엔진기반에 multiple IE6으로 볼때는 position:fixed를 적용을 하더군요… 저도 이 문제를 생각도 못하다가 다른분 컴퓨터의 IE6을 보고야 알았습니다 -_-;;;

  21. 정찬명 댓글 | 2008년 3월 24일, 10:16

    네, 사실 저도 실무에서 이 코드 적용을 시도했다가 결국 포기했습니다. 극복해야 할 문제가 좀 있죠 ㅡㅡ;

댓글 남기기.

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



본문 | 검색 | 글 분류 | 최근 글 | 최근 댓글 | 기타 | 위로