IE6에서 레이어 고정시키기 핵. Fixed Layer Hack for IE6.
CSS에는 position:fixed 라는 속성이 존재하고 이 속성이 부여된 엘리먼트는 화면에 고정되어 스크롤을 해도 움직이지 않고 항상 같은 자리에 머물게 됩니다. 흔히 "스크롤을 따라다니는 배너" 라고 표현하는 이런 UIO(User Interface Object) 따위를 코딩할 때 이 속성을 사용할 수 있는데 보통의 경우 IE6에서 지원하지 않기 때문에 별도의 자바스크립트를 추가하여 이 기능을 구현해 왔습니다. 하지만 이제는 더이상 그럴 필요가 없을것 같습니다. 자바스크립트는 전혀 사용하지 않고 CSS Hack을 사용하여 IE6 에서 position:fixed 상태의 레이어를 구현할 수 있는 팁을 발견하였습니다.
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 에서만 발생하는 현상입니다.
브라우저의 기본 스크롤을 컨트롤 하는 방법이라 적용하기가 살짝 두렵네요 ^^;;
ie6에서 창을 줄였을 경우 세로스크롤에 문제도 조금 있구요(레이어가 스크롤 위로 올라가는… 위치도 살짝 ^^;;)
소스를 약간만 보완하면 좋은 팁이 될거 같네요~ 좋은 정보 감사요~~~
아~ 브라우저 크기를 줄였을 때 레이어가 스크롤을 덮어버리는군요. 이거 아직 끝나지 않은 숙제인걸요. 정윤님, 좋은 해결방법이 없을까요?
예전에 이 방식을 보고 적용해서 작업했던 적이 있는데 이런 원리였군요.
위엣 분이 얘기하신 문제는 저도 겪어봤는데 +_+ 원리를 알면 해결책도 알 수 있는 법!!
javascript 의 onload, onresize event 에서 viewpoint 사이즈를 얻은 후 body 의 height 를 height(viewpoint)-height(fixed layer) 로 조정해주면 해결이 가능하지 않을까요?
일단, Javascript 를 사용하지 않고 이 문제를 해결 할 수 있는 방법이 있는지 이 글을 보신 분들과 함께 연구해 보면 좋겠네요. 저도 틈날 때 연구해 보겠습니다. 지금으로서는 딱히 떠오르는 생각이 없지만 ㅡㅡ;
와… 이런 방법이 또 있나요?
별나라 이야기 같습니다만… 언젠가 써먹을일이 있을 때 매우 유용할 듯 싶습니다. ^^
감사합니다~~
흥미로운 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 픽셀의 간격이 생기는데요…왜 마진이 생기는지 설명은 안되지만 나름 발견한 문제여서 글을 남깁니다…
(정찬명 님께서 올리신 글하고는 크게 상관은 없는 것 같지만 딱히 올릴만한 곳을 찾지 못해서..)
좋은 정보네요.^^
이런방법도 있구나~하면서 놀랍고 제공해 주셔서 감사합니다. 잘쓰겠습니다.
조준희님께, 답변이 엄청 늦었네요. 기다리셨다면 죄송합니다 (__)
정체불명의 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이 되거든요.)
설마 도움이 되시려나요? ^^
이은주님, 반갑습니다 ^^ 사용시 부작용 꼼꼼하게 읽어보시고 사용해 주세요 (__)
코드를 약간 수정하였습니다. #aside 레이어가 스크롤을 덮는 문제를 _z-index:-1 으로 해결했습니다. 그러나.. #aside 영역의 텍스트를 드래그 하거나 링크의 클릭이 되지 않습니다. 쉬뜨.. 해결사 어디 없나요? ㅡㅜ; (현재로서는 네비게이션 요소만 아니라면 일단 쓸 수는 있겠네요.)
허걱.. 이렇게 좋은 정보를 몰래콤시 올려놓으시다닝~!!
제 글에 트랙백 달아주세요옹~*
(제가 달려고 하니, 뭔가 좀 거시기한거 같아서 -ㅛ-;;)
하하~ 몰래콤시 올려놓은 것은 아니구요~ 요한씨 글에 댓글을 적었는데 어느순간 지워져 있더라구요. 요한씨의 필더링 시스템 때문인지 아니면 제가 글을 적어놓고 전송버튼을 안눌렀던가.. 그랬던 모양이에요. 늦었지만 결혼 축하드리구요. 직접 가서 축하해줬어야 하는데 그러지 못해서 미안했어요. ^^
아니에요~, 축하만 해주셔도 감사한걸요~ㅎㅎ
동생이 발견한 방법인데요.
_top:expression(documentElement.scrollTop + (documentElement.scrollTop>120?스크롤뒤의높이 :처음높이-documentElement.scrollTop));
이렇게 하면 완벽하게 Fixed포지셔닝이 가능해지더군요.
콩바구니님, 의견 감사합니다. 콩바구니님의 코드가 포함된 예제페이지를 한번 볼 수 있을까요?
이크. 여기는 댓글 한번작성하면 수정할수 없나보네요.ㅠㅠ
_top:expression(documentElement.scrollTop+ 높이);
_top:expression(documentElement.scrollTop + (documentElement.scrollTop>갑?을:병-documentElement.scrollTop));
갑: 처음 높이값
을: 스크롤하는동안의 높이값.
병: 갑+을
이게 맞습니다.
처음방법은. 일반적인 Fixed포지션이고,
두번째방법은 조금더 발전된방법이랄까요. 스크롤이 내려갈때의 위치를 따로 지정할수 있습니다.
제 블로그에 바로 적용했지요.
적용한 css 파일의 주소는
http://cfs.tistory.com/custom/blog/2/24447/skin/images/style_ie6.css 입니다.
아넵, 잘 봤습니다. 그런데 한가지 궁금한건요. expression을 사용했을때 아무런 문제상황이 발생하지 않으리라는 보장이 있나요? 표준이 아니라는 문제를 제외하고 페이지의 성능등에 영향을 미치지 않는지 궁금합니다.
expression을 사용했을때 잘못하면 특정상황에서 무한루프에 빠질수 있기때문에 사용을 자제하라는 말이 있더군요. 자세한문제는 잘 모르지만… 제 블로그에 적용해보고 시험해본결과. 한두개의 Fixed포지셔닝에 활용하는정도로 페이지의 로딩이 느려진다거나.CPU점유율이 높아진다거나. 하는 현상은 보이지 않았습니다.
이번 프로젝트에 팝업 상단 부분을 고정시키기 위해 이 포스트를 참고하여 적용해봤는데 결정적인 문제가 있더군요… 고정시키려는 부분 외에는 relative나 absolute 포지셔닝을 사용할 수가 없네요 적용하면 그 부분도 역시 고정이 되어버리기 때문에… ^^;
특별히 포지셔닝을 하는 부분이 없다면 괜찮겠지만 사이드바에 사용하기엔 위에 있던 약간의 문제들도 있고 실무에서 사용하기엔 약간 위험부담이 있을 것 같습니다.(저같은 경우는 팝업컨텐츠가 특별히 포지셔닝을 사용하는 부분이 없어 일단 유지하고 있습니다)
덧붙여 이번에 안 문제지만 IE7엔진기반에 multiple IE6으로 볼때는 position:fixed를 적용을 하더군요… 저도 이 문제를 생각도 못하다가 다른분 컴퓨터의 IE6을 보고야 알았습니다 -_-;;;
네, 사실 저도 실무에서 이 코드 적용을 시도했다가 결국 포기했습니다. 극복해야 할 문제가 좀 있죠 ㅡㅡ;