Html & Script

CSS 이야기(3)

페이지 정보

본문

0. 들어가며
좀 더 예쁜 예를 만들고 싶은데 디자이너가 아닌지라.. 예가 허접해도 이해하며 봐주시기 바랍니다. 전에 있던 회사에서는 제가 코딩까지 다 한지라 CSS 디자인을 그럭저럭 많이 써서 예를 들수가 있는데, 새로 옮긴 이 회사에서는 디자이너가 드림위버로 통짜로 주는지라... 거기에 php 끼워넣는 것만으로 허덕대서 최근에 작업한 걸로는 예를 드릴 수가 없어서.. 새로 만들어야 해요.. T_T
일단, 여기 예로 든 것들은 CSS나 XHTML Validator를 돌리지 않은 예입니다. 혹시 일부러 돌려보고 에러난다고 우기시면 울어버릴지도. -_-a 급하게 예를 만드느라 에러만 안나면 그냥 썼습니다. 양해해주세요.



1. Full CSS 디자인을 위한 준비.
1) 완성될 문서의 구조가 먼저 잡혀있어야 합니다.
대개의 경우 페이지의 레이아웃은 먼저 잡혀있기 마련입니다. 이것을 얼마나 논리적으로 잘 쪼개느냐가 구조화된 문서로 가는 지름길입니다.
일단 분할의 기본은 사각형입니다.
현재 PHP스쿨의 메인 화면을 예로 든다면...
- 상단헤더(로고 + 우측 배너 광고)
- 검색 바
- 좌측 메뉴단
- 스폰서 링크단
- 중앙 컨텐츠단
- 하단 푸터

등으로 나뉠 수 있습니다.
이렇게 각각을 분할해도 좋고... 좀더 체계적이길 원한다면

- 상단헤더
- - 로고부문
- - 배너 광고 부문

- 중단 컨텐츠
- - 검색바
- - 메인 섹션
- - - 좌측 섹션
- - - - 메뉴
- - - - 스폰서 링크
- - - 우측 섹션
- - - -  Notify
- - - - Survey
- - - - 중앙 광고 1
- - - - News
- - - - Downloads
...

이런 식으로 좀 더 계층구조를 명확히 나누는 방법도 있습니다.
각각이 장점이 있는데,  동일한 층위의 레이어로 분할한 경우에는 CSS 디자인시 포지셔닝에 대해 훨씬 자유로울 수 있습니다. 대신 일일이 absolute로 포지션을 지정해줘야하는 귀찮음이 있죠.
계층별로 세분화한 경우에는 absolute보다는 relative로 포지션을 잡아야하죠. 이 경우의 장점은 보다 상위 계층의 레이어의 포지션을 바꿔도 하위 계층의 레이어는 상위 계층의 레이어를 중심으로 배열이 되기 때문에 덩어리로 움직일 때 좋습니다. 완전히 디자인 구조가 바뀌어야 한다면(예를 들어 메뉴 중 일부를 떼어다가 상단에 붙인다던가 할 경우..) 전자겠지만, 어느정도 틀이 있고 그 선에서 디자인의 변경이 들어간다면 후자쪽이 훨씬 나은 방법입니다.

실제적으로 분할했을 경우에는 각각의 부분을 <div>로 잡아주시면 됩니다. 예를 들면 다음처럼이겠죠.
<div id="top_header">
<div class="logo">
로고 부분...
</div>
<div class="banner">
배너 광고부분..
</div>
</div>
...

그럼 여기에서 CSS positioning에 대해 알아보고 넘어가야겠지요?
모든 HTML 엘리먼트(태그라고 생각하시면 되요.)는 position이라는 CSS 속성을 지닙니다.
static, relative, absolute, fixed의 네가지 속성이 있는데, fixed는 사용되지 않습니다.
static은 position을 따로 지정하지 않았을 경우의 엘리먼트의 위치를 따릅니다. top이나 left같은 위치 이동 속성을 줄 수가 없지요.
relative는 현재 엘리먼트보다 상위 엘리먼트를 기준으로, 현재 엘리먼트의 위치에서의 상대좌표에 의한 위치 지정을 하게 합니다.
absolute는 페이지 좌표(브라우저 좌표)를 기준으로 한 절대좌표의 위치 지정입니다.
일단 예를 보죠.

http://eouia.net/temp/css1.html

소스보기를 해서 style 부분을 봅시다.
test이라고 표시된 빨간 박스는 relative로 지정했고, test2라고 표시된 녹색 박스는 absolute로 지정했습니다. 소스를 보시면 아시겠지만 test class의 상위 엘리먼트는 <body>입니다. 현재 편의상 body를 margin:0px, padding:0px로 잡아 좌표의 기준점을 브라우저의 좌상단모서리로 잡았습니다.
absolute 속성은 이해하기 쉽습니다. 무조건 브라우저의 좌상단 모서리를 기준으로 삼아 top만큼 아래로, left만큼 오른쪽으로 이동한 위치가 좌표점이 됩니다. 그래서 test2 녹색 박스는 브라우저 좌상단을 기준으로 (10px,10px) 이동한 위치에 표시되었습니다.
relative 속성은 다른데, 현재 엘리먼트가 속한 상위 엘리먼트(이 경우에는 body)속에서 자신이 원래 위치했어야할 좌표에서 top만큼 아래로, left만큼 오른쪽으로 이동한 위치가 좌표점이 됩니다. 그래서 test 빨간 박스는 body안에서의 자신의 원래 자리 (지금의 경우에는 body의 기준 좌표점이 브라우저 좌상단 기준과 동일하므로 0px, 0px)에서 top과 left만큼 이동한 50px, 50px에 위치하고 있습니다.

한번 body의 margin을 바꿔서 body의 기준 좌표점이 브라우저 좌상단 모서리와 일치하지 않도록 해보겠습니다.

http://eouia.net/temp/css2.html

body에 margin:50px, 10px를 주어 기준 좌표점이 브라우저 좌상단으로부터 50px, 10px 만큼 이동한 경우입니다. 앞의 예와 비교해보면 absolute 속성의 녹색박스의 위치는 그대로인데, relative 속성의 빨간박스는 50px, 10px 만큼 이동한 것을 아실 수 있습니다. 즉, 상위 엘리먼트인 body의 기준좌표에 relative 속성의 하위 엘리먼트가 연동하는 것을 보실 수 있습니다.

absolute 포지셔닝을 하실 때 주의점은 상위 엘리먼트가 absolute 포지셔닝이 아니라면 포지셔닝이 제대로 먹지 않을 수도 있습니다. 즉, absolute로 위치 지정을 하려면 상위 엘리먼트도 absolute로 위치 지정이 되어야만 합니다. body의 경우 최상위 엘리먼트이기에 따로 absolute로 지정하지 않아도 absolute로 지정되어 있습니다.

사실 이렇게 강제적인 포지셔닝의 지정은 개인적으로는 별로 마음에 들지 않습니다. 일반 로컬 어플리케이션을 작성하셨던 분들이야 이렇게 강제로 좌표지정해서 디스플레이하시는게 익숙하시겠지만.
저로서는 absolute는 거의 쓰지 않고,  relative도 아주 특별한 경우가 아니라면 자제합니다. 그럼 어떻게 위치를 맞추냐구요? 잘 구조화한 후 width와 height, margin(그리고 아주 특별한 경우에는 float) 속성만 가지고도 충분히 위치를 잡을 수 있습니다.

2) 분할의 기준은 수평선.
다시 문서 구조화의 이야기로 돌아가서. 문서의 레이아웃을 div로 분할하실 때 사각형으로 분할하시라고 말씀드렸지만, 그 기준이 되는 것은 수평선입니다. 먼저 수평으로 레이아웃을 분할하신 뒤, 요소에 따라 수직으로 재분할, 다시 그 안에서 수평으로 분할, 다시 수직 분할...
말로는 이해가 어려우실 테니 그림을 보죠.

http://eouia.net/temp/cssimage1.jpg

왼쪽과 같은 구조의 문서를 레이아웃 잡기 위해서는 오른쪽 처럼 분할하는 게 일반적입니다. 우선 붉은 색처럼 수평 기준으로 삼단으로 분할한 후, 각각의 안에서 수직 기준으로 푸른색으로 분할, 다시 그 안에서 수평 기준으로 녹색으로 분할.... 개발자 분들은 구조화에는 나름대로 일가견이 있으실 테니 그림만 보셔도 무슨 뜻인지 아실 겁니다.
이렇게 분할한 후 각각을 div 태그로 싸주시면 되지요. (노파심에 말씀드리지만, id와 class를 부여안하시고 <div>만 덜렁 써주심 안되요. ^_^)

문서 전체의 구조화라든가 form에서 각 요소들의 구조화라든가.. 전부 마찬가지입니다.

3) form 디자인...
다음은 이런 식으로 구조화한 form의 예입니다.

http://eouia.net/temp/css3.html

디자인은 허접.. T_T 일부러 알아보기 쉽게 하기 위해 색깔을 넣었습니다. 촌스럽지만 양해해주시고... 역시 소스보기를 먼저 해보세요. 실제로 문서내에 들어있는 내용이 매우!! 간략한 것을 알 수 있습니다. 왜냐하면 디자인 요소들을 전부 빼버림으로 인해
table등은 하나도 쓰지 않고, fieldset과 label만 가지고 디자인했습니다. 사실 label대신 div를 쓰셔도 됩니다만, label은 form 컨트롤의 라벨을 위해 존재하는 태그이니 이왕이면 label을.
잠깐 삼천포로 빠져서 label을 사용함으로써 얻는 이득을 설명...

<input type="radio" name="sex" id="male">
<label for="male">"섹스"를 "매일"해서 "male"??</label>

label 태그는 클릭하면 label for로 연결된 컨트롤을 클릭한 효과를 줍니다. radio버튼이나 checkbox에서 매우 유용하겠죠?
이외에도 label을 쓰는 이유는 기계나 프로그램이 해당 컨트롤이 무엇에 관한 컨트롤인지 이해하기 쉽다는 장점이 있죠.

fieldset은 여러가지 용도로 쓰이지만, 대부분 form 안에서 컨트롤간의 구분을 위해 쓰입니다. border:none 속성을 주지않으면 border가 디폴트로 들어가니까 주의하세요.

사실 이 소스만 제대로 이해하셔도 제가 이야기할 것의 절반 이상이 끝납니다만, 차차 이야기하도록 하고, 여기에서는 float이라는 속성에 대해 더 알아보죠.
float은 현재 엘리먼트 다음에 나오는 엘리먼트 기준으로 현재의 엘리먼트를 어디에 위치시킬까를 결정합니다.
위에서 분할의 기준을 수평선으로 잡는다고 했는데, 하나의 수평 블록안에 여러개의 엘리먼트를 위치하는데 display:inline과 span 태그와 함께 유용하게 쓰입니다.
지금의 예처럼 .fld_name 클래스에 float:left; 속성을 준 경우 다음에 나오는 .fld_password 클래스의 "왼쪽"에 .fld_name 클래스를 위치한다는 뜻입니다. 그럼 float:right;로 줬다면 어떻게 되었을까요?
눈치빠른 분은 답을 아시겠지만.. .fld_name클래스가 .fld_password 클래스의 "오른쪽"에 위치하게 됩니다.
.fld_password 이후에는 더이상 이러한 float 속성이 필요없으니 .fld_password클래스에는 float:clear;를 줘서 더이상 float이 적용되지 않도록 했습니다.
보통 float속성은 다른 엘리먼트와 영역이 겹칠 경우 왼쪽과 오른쪽 어느쪽으로 배열할지를 결정하는데 쓰입니다.


4) 디자인과 컨텐츠를 구별합시다.
좋은 CSS 디자인을 위해서 조심해야 할 몇가지 명제가 있는데 그 중 하나가
"img 태그를 남발하지 않는다."
라고 할 수 있겠네요.
img 태그를 쓰지 말라는 이야기는 아닙니다. 신문기사에 들어가는 사진같은 "컨텐츠"라면 img 태그를 쓰는게 당연하죠.
하지만 단지 페이지 장식을 위해, 버튼 이미지를 위해 img 태그를 쓰는 건 삼가해주세요.
대신 background-image:url(); 속성을 사용하세요. 위의 폼 예제에서 버튼 부분이 바로 그렇게 되어있습니다.
단지 디자인을 위한 img 태그는 문서의 재활용에 아주 심각한 문제를 일으킵니다. 소스가 복잡해지는 것은 물론이고, CSS 를 이용해서 크로스 플랫폼용 문서를 만들때에도 문제가 됩니다.
img 태그를 안썼다면 CSS에 몇줄 추가하는 것만으로 프린트용 버전을 만든다거나, Aural 페이지를 만든다거나 할 수 있는데, img가 들어가면 이게 말짱 꽝입니다.
background-image:url(); 속성은 모든 엘리먼트에 다 추가할 수 있습니다. div같은 일반 태그 뿐만 아니라, 각종 form 컨트롤이라든가..
그외에도 재밌는 활용이 많죠. 요건 다음 기회에 소개하도록 하구요, 어쨌거나 디자인과 관련된 부분은 모두 과감하게 CSS에게 일임하세요.


에구.. 아직도 풀어놓을 말은 많은데 너무 지치네요. 나머지는 다음 기회에.. 좀 정리되지 못한 감이 있는데, 나중에 다시 한번 제대로 정리할 기회가 있겠죠.

관련자료

등록된 댓글이 없습니다.
Today's proverb
절벽에서 떨어지고 있는 상황일지라도 아무것도 할 수 없는 것은 결코 아니다. 떨어지고 있으니까 하늘을 향해 날 수 있지 않은가? (로버트 슐러)