CSS 절대 위치를 사용한 프레임 효과

dev | 2011-05-26

프레임 셋을 사용하면 여러 파일을 관리해야 되고 요즘은 서버쪽 언어 없이 개발 되는 웹사이트도 거의 없기 때문에 프레임 셋을 이용해서 제작되는 사이트는 거의 없다. 또한 페이지 분할이 필요할 때에도 CSS로 이를 구현할 수 있기 때문에 프레임 셋을 사용할 경우는 로컬 환경에서 사용할 경우밖에 없는 것 같다.

CSS로 프레임 효과를 만들기 위해서 이해해야 할 속성 값은 auto이다. 레이아웃 가운데 정렬에서도 좌우 여백을 auto로 지정을 하면 브라우저가 알아서 좌우 여백을 지정한다. 절대 위치를 지정한 박스에서도 높이나 너비를 auto로 지정(기본값)하면 오프셋에 따라서 높이와 너비가 결정된다. 이를 이용해서 화면에 박스들이 화면 크기에 따라서 바뀌게 레이아웃을 구현할 수 있다.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Frameset like layout using absolute position</title>
<style type="text/css">
body {
	margin: 0;
}
header {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 100px;
	background-color: #ccc;
}
article {
	position: absolute;
	top: 100px;
	bottom: 50px;
	left: 0;
	right: 200px;
	overflow: auto;
}
aside {
	position: absolute;
	top: 100px;
	bottom: 50px;
	right: 0;
	width: 200px;
	overflow: auto;
	background-color: #eee;
}
footer {
	position: absolute;
	bottom: 0;
	left: 0;
	right: 0;
	height: 50px;
	background-color: #ccc;
}
</style>
</head>

<body>
<header>Header</header>
<div id="body">
	<article>Article</article>
	<aside>Aside</aside>
</div>
<footer>Footer</footer>
</body>
</html>

HTML5 마크업을 썼기 때문에 IE에서 태그들이 인식되도록 아래와 같이 createElement를 이용해서 요소를 만들어준다.

<!--[if IE]>
<script type="text/javascript">
document.createElement('header');
document.createElement('aside');
document.createElement('article');
document.createElement('footer');
</script>
<![endif]-->

IE6 이하 버전에서는 이 기법을 이용해서 박스 크기를 설정할 수 없다. IE6에서 페이지를 열어보면 푸터가 중간에 걸치는 것을 볼 수 있다. 콘텐츠를 사용 못하게 가려서는 안되기 때문에 절대 위치를 풀어버리고 전체 스크롤이 생기도록 처리하면 충분하다.

<!--[if lte IE 6]>
<style type="text/css">
header, 
article, 
footer {
	position: static;
	display: block;
}
article {
	margin: 0 200px 0 0;
}
footer {
	margin: 0 200px 0 0;
}
</style>
<![endif]-->

일반적인 웹사이트에서는 쓸모가 많지 않겠지만 위젯같이 작은 화면안에 독립적인 인터페이스를 만들때에는 유용하게 사용될 수 있다. 물론 그러한 특수한 환경에서는 브라우저가 정해져 있기 때문에 IE 엔진을 사용하지 않는 한 IE를 위한 처리는 안해도 된다. 예시 페이지.

Comments

  • peecky 2011-05-26

    createElement() 를 저런식으로 쓰는건 처음보네요. 브라우저가 모르는 tag라도 해당 element들이 CSS 적용을 받도록 해주는 역할인가요? 혹시 관련 문서가 있으면 소개 좀 해주세요 :)

  • 신현석 2011-05-26

    일종의 트릭입니다. http://trend21c.tistory.com/913 참고하세요~

  • slur 2011-05-30

    여담입니다만, Gecko1.8x 엔진 기반의 브라우저를 사용하면 본 블로그의 레이아웃이 이상하게 표시되네요. 브라우저 폭과 관계없이 wide로 표시되고, 좌우 스크롤바 없이 가로 기준으로 가운데만 보입니다. firefox2.0.0.19와 K-Meleon1.5.4로 확인했습니다.

  • 신현석 2011-05-30

    다단이 없이 표시된다면 의도된 것입니다. 미디어 쿼리가 지원되지 않는 브라우저에서는 레이아웃이 풀어져 보이도록 제작했습니다. 그런데 말씀 들어보니까 max-width 정도는 지정해주는 것이 좋겠네요. 그래서 max-width는 지정했습니다. 그런데 Browser Shot 사이트에서 파이어폭스 2.0.0.19랑 K-Meleon1.5에서는 레이아웃이 잘 나오는거 같은데 Browser Shot 사이트가 제대로된 결과를 보여주지 못하는 것인지 잘 모르겠네요.

  • slur 2011-05-30

    아차, wide로 표시된다고 쓴 건 제 실수네요 다단이 없이 표시되는 것이 아니라 단 구조로는 표시되는데 브라우저 폭이 페이지폭보다 좁을 때도 가로 스크롤이 없이 가운데쯤에 고정된 상태로 표시된다는 의미였습니다 http://img856.imageshack.us/img856/4573/768x768kmeleon154.png http://hyeonseok.com/share/theme/brown/brown_wide.css를 블락하면 IE6에서처럼 단이 없는 구조로 표시됩니다

  • slur 2011-05-30

    imageshack이 예전하고 다르네요 캡쳐 화면을 다른 곳에 다시 업로드합니다 http://www.freeimagehosting.net/uploads/eafc42456a.png

  • 신현석 2011-05-31

    파이어폭스가 3.5때부터 미디어 쿼리를 지원했는데 그 이전 버전에서는 읽지 않아야 할 스타일까지 읽어버리는 media 속성 해석 버그가 있네요. 어떻게 할까 고민하다가 내용을 파악할 수 없는 것이 가장 큰 문제이기 때문에 좌우 스크롤이 생기게끔 했습니다. 덕분에 몰랐던 사실을 알았고 이를 방지할 수 있는 팁을 하나 얻었네요. 감사합니다.

  • direct 2011-07-14

    이제 막 CSS로 레이아웃 짜는것에 입문했습니다. 제 이름은 조현석이구요 ㅎㅎ 반갑습니다. 많은 글들 다 도움이 되지만, 레이아웃 짜는 것에 있어서 이글이 특히 간단하고 쉽네요. 기존의 DIV 태그를 이용해서 칼럼과 로우로 나누던 레이아웃은 아무리 해봐도 이해가 어려워서 헤매었었는데, 이건 쉽게 이해되고 활용도가 높아보입니다. 그래서 여쭤보려고합니다 DIV 태그를 이용해서 프레임을 만드는데에 가장 난해했던 부분이(그래서 포기했습니다) DIV 를 프레임처럼 역할시키면서 프레임이름을 걸어주고 다른 링크들이 그것을 베이스타겟으로 삼도록 하는 방법, 그리고 DIV 안에 아이프레임을 이용하지않고 다른 문서들을 표시할수 있도록(프레임으로서 역할이 이게 가장 크다고 생각됩니다) 하는 방법을 몰랐던 겁니다. 알아보다 보니 DIV태그만으로는 불가능한 방법이라고 하더군요. 혹시 이렇게 레이아웃을 짜게 되면, 베이스타겟을 설정할 수 있는지, 설정한다면 프레임이름은 어떻게 지정해 주는지, 그리고 아이프레임이 아닌 방법으로 프레임으로서의 역할을 할 수 있는지가 궁금합니다. 초보라 질문이 너무 많네요. 같은 이름이니까 어여삐여겨주세요^^

  • direct 2011-07-14

    찾다보니 더이상 타겟은 표준이 아니며, 인클루드를 사용해야 한다고 들었습니다. 그런데 css 관련 발번역 서적에서나, 아니면 현석님 블로그처럼 css 관련 글들에서 인클루드를 한번도 찾아볼 수 없었던 이유가 무엇일까요? (제가 검색을 덜해서 그런거겠지만^^) 지금 인클루드 찾아보는 중입니다만, 혹시 css의 범위에서 벗어나는 언어인지 궁금합니다.

  • direct 2011-07-14

    이전에 쓴 글을 어떻게 지우는지 모르겠네요 ㅠ 지금까지 모아온 정보에 의하면, 이전에 하던 테이블레이아웃대로 하면, 한 페이지안에서 컨텐츠가 들어갈 부분에 아이프레임을 작성하고, 베이스타겟을 아이프레임으로 하여 한 페이지안에서 다른 페이지들을 불러들이는 방식으로 제작했었습니다. 웹표준의 경우에는, 링크를 클릭하면 페이지 전체가 다시 리로딩되는 방식이고, 각 페이지마다 헤더와 푸터, 그리고 사이드바를 포함(인클루드)시키는 것 같습니다. 그리고 인클루드를 적용시키려면 파일을 PHP 형식으로 저장해야하는 것 같구요. (드림위버에서 PHP 형식으로 새문서를 열면 HTML 과 동일한 기본코딩이 되어 시작되네요. 언어상 특별한 것을 제외하고는 HTML처럼 작성하면 되는 것같습니다.) 즉 기존에 저는 index.html 이라는 헤더 푸터 메뉴가 포함된 문서안 아이프레임에 1.html, 2.html 을 불러들이는 방식이었고 웹표준은 1.html, 2.html 등등의 각 문서안에 헤더와 푸터, 사이드메뉴등이 인클루드된 형식으로 제작된다. 라는 것이겠지요? 일년전에 공부하다가 도무지어려워서 때려친걸 이제 조금씩 이해해갑니다. 주저리주저리 잡설이 길었네요. 앞에 글들을 어떻게 지우는지 몰라, 그대로 둡니다. 지저분한 질문 죄송합니다ㅠ

  • 신현석 2011-07-14

    1. 그냥 프레임셋 쓰시면 될 것 같은데요. 프레임셋도 HTML 4.01 Frameset 표준입니다. 2. 타겟 속성은 HTML 4.01 Transitional에 정의되어 있는 표준 속성입니다. 3. 인클루드는 서버측 기능이어서 웹표준과 크게 관련이 없습니다. http://hyeonseok.com/pmwiki/index.php/Main/Include 궁금하신 내용있으시면 언제든지 글 남겨주시거나 메일 주세요. :)

  • direct 2011-07-14

    그렇군요! 검색에서는 유언비어가 많네요 ㅎ 그래도 찾아가는 과정에서 많은걸 배웠습니다. 친절한 답변 감사합니다^^

  • 이태훈 2012-08-04

    유용한 정보 감사합니다. 그런데 HTML5 같이 div를 안쓰고 하는 코드 같은데, 신기합니다. 아까 div로 바꿔볼려고 했는데 잘 안되더라구요. ^^;; 그런데 <div id="body"> 하고 상위의 <body> 하고 무슨 차이인가요? 많이 신기합니다. 수고하세요. ^^

  • 신현석 2012-08-04

    <body>는 body 요소, <div id="body">는 div요소인데 id값이 body인 요소입니다. 별 관련은 없습니다.

  • cy 2016-03-05

    질문이요... 그럼 위 처럼 하면 프레임셋 쓰는것처럼 타겟을 줄수 있나요?? 원프레임이니 링크시 모두 로딩인가요?? 아니면 예를 들면 컨텐츠 타겟을 주어서 컨텐츠만 로딩이 되는건가요?? 예) 네이버 메일을 보면 원페이지인데 왼쪽 각메뉴(받은편지,보낸편지)를 누르면 컨텐츠만 로딩을 하더라구요

  • 신현석 2016-03-06

    프레임처럼 보이는 것일 뿐 실제 프레임이 아닙니다. 그냥 링크를 걸 경우 모두 로딩됩니다. 일부 페이지만 로딩하려면 자바스크립트로 콘텐츠 로딩을 제어해야 합니다.

Post a comment

:

: 공개 되지 않습니다. Gravatar를 표시 합니다.

:

: HTML 태그를 사용할 수 없습니다.