이미지를 나열할 때 생기는 간격은 img 부모 요소 div에서 font-size: 0 으로 설정하면 된다.


===================================================================================


CSS로 이미지 정렬하기

엄격한(Strict) 문서 규격 정의(DTD)에서는 이미지 정렬에 흔히 사용되던 align 속성을 허용하지 않습니다. 따라서img 태그만으로는 이미지의 위치를 자유롭게 조절할 수 없고, 반드시 CSS를 함께 사용해야만 합니다.

단순히 하나의 이미지만 넣어야 할 경우에는 text-align이라는 CSS 속성으로 간단히 해결할 수 있지만 현실적으로는 이보다 훨씬 복잡한 경우가 많습니다. 특히 이미지와 텍스트를 함께 배치하려면 어쩔 수 없이 float 속성을 사용해야 하는데 이 속성에 대한 해석이 브라우저에 따라 차이가 있으므로 브라우저 호환성 면에서 생각보다 훨씬 많은 위험성을 갖고 있습니다. 이렇게 까다로운 이미지 태그를 잘 사용하기 위해 알아두어야 할 점과 float 속성으로 이미지를 정렬하는 방법에 대해서 정리해봤습니다.

† 앞으로 제시할 모든 예는 noimgstyle class가 적용된 div 안에 넣었고, 기본적으로 적용된 속성은 아래와 같습니다. 그 외의 모든 CSS 규칙은 인라인 스타일로 정의했으므로 소스를 확인하면 각 예에 적용된 속성을 확인할 수 있습니다.

.noimgstyle { border: 1px solid #699; padding: 1em 1em 0 1em; margin-bottom: 1em; line-height: normal; height: 1%; }
.noimgstyle img { border: none; margin: 0; padding: 0; display: inline; }
.noimgstyle p { text-align: justify; margin-bottom: 1em; }
.noimgstyle span { background-color:#666; color: #fff; }

인라인(inline) 레벨 요소인 img 태그

일반적으로 이미지는 직사각형의 영역을 갖고 있습니다. 따라서 div, p, blockquote 등의 태그처럼 블록(block) 레벨에 속한다고 착각하기 쉽지만 실제로는 일반 텍스트와 동일한 인라인 요소입니다. 따라서 특별한 처리 없이 사용될 경우 아래 예처럼 텍스트의 한 글자처럼 취급됩니다.

글자처럼 test image 취급되는 test image image

그런데 동일한 인라인 요소임에도 줄이 제대로 맞지 않는 것을 볼 수 있습니다. 이것은 알파벳의 g, p, y 등의 문자에서 베이스라인 아래로 내려오는 꼬리(descender)를 위한 영역 때문입니다. 즉, 이미지를 꼬리가 없는 i 문자처럼 취급한다는 얘기지요.

이 사이 간격을 없애는 방법은 많이 알려져 있습니다. 첫 번째는 이미지를 감싸는 상위 요소(div 등)의 높이를 이미지와 같도록 해주는 것이고, 두 번째는 CSS의 vertical-align: text-bottom 속성을 지정하는 것입니다. 이미지를 블록(block) 요소로 보이도록 하는 세 번째 방법은 나중에 알아보고 일단 vertical-align: text-bottom 속성을 적용한 이미지를 보겠습니다. CSS를 인라인 스타일(inline stye)로 지정했으므로 소스를 확인하면 바뀐 부분을 확인할 수 있습니다.

글자처럼 test image 취급되는 test image image

† 인라인 이미지와 텍스트의 배치를 결정해주는 vertical-align 속성에는 많은 브라우저 호환성 문제가 있습니다. 특히 line-height 속성과 결합되면 심각한 문제가 생길 수 있다고 하네요. 일반적으로 발생하는 문제가 아니기에 추가적으로 설명하지는 않겠습니다. 어떤 문제가 있는지 알아보려면 이미지 수직 정렬과 line-height와의 관계와 긴 이미지와 line-height와의 관계 페이지를 인터넷 익스플로러와 파이어폭스에서 비교해 보시기 바랍니다.

블록(block) 레벨 요소로 보이는 이미지

이미지를 인라인 요소가 아닌 블록 요소로 보여지도록 해야 할 경우가 있는데 이 때 사용되는 것이 CSS의 display속성입니다. 먼저 알아두어야 할 것은 이 속성이 HTML 요소가 어떻게 보여질지만을 바꿀 수 있다는 점입니다. 다시 말해서 인라인 요소를 블록 요소로 바꾸어주는 것이 아니라는 것이지요. 간단한 예를 들자면 HTML 규격상 인라인 레벨 요소는 블록 레벨 요소를 포함할 수가 없습니다. 따라서 인라인 요소인 span 태그에 display: block; 속성을 지정한다고 해도 span 태그 안에 p 태그는 들어갈 수 없습니다.

하지만 인라인 요소를 블록 요소로 보이게(display) 하면 이미지 위, 아래에서 줄바꿈(line break)이 생깁니다. 아래 예는 이미지에 display: block; 속성이 적용되었을 때의 결과입니다.

블록으로test image취급되는test imageimage

† 이미지와 텍스트에 적용되는 line-height 속성 때문에 서로 다른 요소가 일부 겹치는 경우가 있습니다. line-height 속성 값을 바꾸어도 문제가 해결되지 않는다면 Designer kukie 님의 오늘의 문제는 line-height라는 글을 참고하시기 바랍니다. 이 문제로 한참을 헤매다가 kukie님이 잘 정리해두신 덕에 해결했습니다. :-)

인라인 이미지 정렬

인라인 이미지는 텍스트와 동일하게 취급되므로 텍스트 정렬에 사용되는 CSS의 text-align 속성이 그대로 적용됩니다. 따라서 중앙 정렬시키려면 이미지를 감싸고 있는 p 태그에 text-align: center;를 지정하고, 오른쪽으로 보내려면 text-align: right;를 사용할 수 있습니다. 아래는 가운데 정렬의 예입니다.

글자처럼 test image 취급되는 test image image

† text-align 속성은 블록 레벨 요소와 테이블 셀(table cell: th, td), 인라인 블록(inline-block)에 적용되고, 해당 요소가 아닌 하위 요소에 영향을 미칩니다(예: 텍스트).

그런데 이미지가 이런 방식으로 텍스트와 함께 사용되는 경우는 드뭅니다. 보통은 이미지 아래에 텍스트가 들어가거나 이미지 옆 공간에 글 단락이 들어가니까요. 텍스트가 아래 배치될 경우에는 p 태그에 이미지만 넣거나 이미지를 블록 레벨로 보이게 하면 되지만 후자의 경우에는 문제가 복잡해집니다. 그럼 왜 문제가 복잡한지 알아볼까요?

이미지에 float 적용하기

이미지 옆에 텍스트 단락을 넣기 위해서는 이미지에 CSS의 float 속성을 주어야만 합니다. 과도적인(Transitional)HTML 문서 규격에서는 이미지에 align 속성을 사용할 수 있지만 엄격한(Strict) 문서 규격에서는 허용되지 않은 속성이기 때문입니다.

먼저 이미지에 float: left; 속성만 적용시킨 예를 보겠습니다. 단락 구분이 잘 보이도록 p 태그에 테두리선을 넣었습니다.

test imageLorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean vel tellus nec massa cursus malesuada. Pellentesque metus.

Proin eu nisi eu tortor consectetuer varius. Curabitur magna nunc, pretium id, tincidunt a, tempus porttitor, nisi. Integer erat lacus, tempor non, varius sit amet, laoreet in, arcu. Pellentesque tempus mauris. Nulla ut ante ut massa suscipit euismod.

이 상태로도 별 문제가 없지만 두 번째 단락을 이미지 옆이 아닌 새 줄에 넣으려는 의도였다면 원했던 결과는 아닐겁니다. float된 요소는 말 그대로 문서 내에서 떠 있는 상태이기 때문에 다른 요소들을 밀어낸 것처럼 보입니다. 또한,float된 요소는 순차적인 요소(box)들의 흐름(normal flow)을 따르지 않으므로 주의해서 사용해야만 합니다.

float 제거하기(clearing float)

float 속성을 적용시켜서 어떤 요소를 띄웠다면 적절한 곳에서 반드시 그 영향을 없애주는 것이 좋습니다. 기본적으로 float된 요소의 높이(height)는 해당 요소가 들어 있는 블록(containing block) 크기에 영향을 미치지 않는데 이런 특성을 없애서 바깥 블록이 float 요소의 높이만큼 늘어나도록 하면 float 특성을 제거할 수 있습니다. 이런float 제거(clearing float) 방법에는 여러 가지가 있습니다.

clear 속성 사용

clear 속성을 이용해서 float을 제거하려면 두 가지 요건이 갖추어져야 합니다. 첫 번째는 float된 요소를 담고 있는 블록(containing block) 안에서 clear 속성이 사용되어야 한다는 것입니다. 아래 예가 이 요건을 갖춘 경우입니다.

<p><img src="somepath" style="float:left" />some text<br style="clear:both" /></p>
<p>some text</p>

하지만 아래와 같이 마크업할 경우에는 브라우저에 따라서 다른 결과가 생깁니다. 이미지를 담고 있는 요소(containing block)은 첫 번째 p 단락인데 clear 속성은 p 단락 밖에서 적용되었으니까요.

<p><img src="somepath" style="float:left" />some text</p><br style="clear:both" />
<p>some text</p>

두 번째 요건은 인터넷 익스플로러에만 해당되는 것으로 float 요소가 포함된 블록(containing block)이 화면상에서 레이아웃을 갖는 요소(haslayout = true)로 인식되어야 합니다. float 문제는 주로 페이지의 레이아웃을 잡을 때 나타나는데 대부분의 경우 float을 포함하는 div에 width나 height 속성을 지정하면서 자동으로 이런 요건을 갖춥니다. 하지만 아래 예처럼 이런 속성이 지정되지 않은 p 태그 안에서는 clear 속성이 인터넷 익스플로러에서만 다르게 적용됩니다. 즉, 인터넷 익스플로러에서는 파이어폭스에서와는 달리 p 태그 높이가 이미지 높이만큼 자동으로 늘어나지 않는 것을 볼 수 있지요.

test imageLorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean vel tellus nec massa cursus malesuada. Pellentesque metus.

Proin eu nisi eu tortor consectetuer varius. Curabitur magna nunc, pretium id, tincidunt a, tempus porttitor, nisi. Integer erat lacus, tempor non, varius sit amet, laoreet in, arcu. Pellentesque tempus mauris. Nulla ut ante ut massa suscipit euismod.

간단한 해결 방법은 Holly hack을 적용시키는 것입니다. float 이미지가 있는 p 태그에 다음과 같은 CSS를 적용시키면 문제가 해결됩니다. width나 height 중 어느 하나라도 정해지면 haslayout 속성이 적용되기 때문입니다.

p { height: 1%; }

float된 이미지의 옆 공간을 채우기 위해서 br 태그를 여러 개 이어서 사용하는 경우가 있는데 좋은 방법이 아닙니다. 그보다는 CSS에 clear를 담당하는 class를 지정해놓고 필요할 경우 적용시키는 것이 좋지요. 흔히 이용되는 코드는 다음과 같습니다.

.clearer { clear: both; }
<br class="clearer" />
<div class="clearer"></div>

한 가지 주의해야 할 점은 <div class="clearer"></div>가 만능은 아니라는 사실입니다. HTML의 컨텐츠 모델에 따라서 동일한 블록 레벨 요소라 해도 p 태그 안에는 div 태그가 들어갈 수 없으므로 상황에 따라서 적절한 태그를 골라서 적용시켜야 합니다.

간단한 방법이지만 float 제거만을 위한 마크업이 추가된다는 단점이 있습니다. 게다가 이미지 옆에 여러 개의 단락이 들어가야 할 경우에는 사용할 수가 없지요. 또한, 위 예처럼 두 개의 단락이 p 태그로 명확하게 구분되어 있을 경우에는 br 태그를 사용할 필요가 없으므로 ‘의미 있는’ 마크업도 아닙니다.

clear 속성이 적용되는 방식

W3C의 clear 속성에 관한 CSS 규격에는 다음과 같이 정의되어 있습니다.

clear 속성은 적용된 요소의 어느쪽 박스 경계가 이전에 float된 박스와 인접하지 않을지를 결정한다. 이 속성은 float된 요소 자체에도 적용되나 이 경우 clear의 효과는 나타나지 않는다.”

clear 속성이 left로 지정되면 clear가 적용된 요소의 박스 상단 마진(margin-top)이 위에 있는 왼쪽으로 떠 있는(left-floating) 박스의 아래 경계에 닿을 수 있도록 늘어나게 된다.”

이런 상황을 잘 설명해주는 이미지를 float 속성에 관한 CSS 규격에서 가져왔습니다.

그림에서 볼 수 있듯이 두 번째 p 블록에 clear 속성이 적용되면 이미지 크기로 인해 생긴 공간만큼 p 블록의 위쪽 마진(margin-top)이 자동으로 늘어나게 되고, 그 결과 블록이 이미지 아래로 내려오게 됩니다. 그러면 실제 예를 볼까요?

<p><img src="somepath" style="float:left" />some text</p>
<p style="clear:both">some text</p>

결과는 아래와 같습니다.

test imageLorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean vel tellus nec massa cursus malesuada. Pellentesque metus.

Proin eu nisi eu tortor consectetuer varius. Curabitur magna nunc, pretium id, tincidunt a, tempus porttitor, nisi. Integer erat lacus, tempor non, varius sit amet, laoreet in, arcu. Pellentesque tempus mauris. Nulla ut ante ut massa suscipit euismod.

먼저 앞서 설명한 float 제거(clearing float) 방법과는 달리 상위 블록이 자동으로 늘어나지가 않습니다. 또한, 인터넷 익스플로러(7 포함)와 기타 브라우저에서 서로 다른 결과가 나오는 것을 알 수 있습니다. 파이어폭스나 오페라 등의 브라우저에서는 이미지와 아래 p 요소 사이에 어떠한 공백도 생기지 않는데 이것이 그림이 나타내는 CSS의 표준 렌더링 방식입니다. 하지만 인터넷 익스플로러에서는 p 태그의 margin-bottom 속성이 float된 이미지에도 적용되기 때문에 이미지와 아래 p 요소 사이에 빈 공간이 들어가게 되지요.

모든 브라우저가 동일한 렌더링 결과를 보여준다면 굳이 float을 없애지(clearing float) 않아도(즉, containing block 길이를 늘리지 않고) 원하는 곳에서 clear 속성을 사용할 수도 있을겁니다. 이미지 아래로 p 태그와 같은margin-bottom을 지정하면 되니까요. 하지만 현실적으로는 몇 가지 문제가 있는데 결정적으로 인터넷 익스플로러에서 이미지 하단과 p 단락 사이의 높이에 따라서 서로 다른 마진을 적용시키기 때문에 크로스 브라우징 면에서 사용하기는 어렵다고 생각됩니다.

† 이 문제에 대한 정보는 이상하게 찾을 수가 없더군요. 그래서 무언가 중요한 요소를 생각하지 못한게 아닌가 하는 생각도 듭니다. 하지만 최소한의 CSS만 적용한 상태에서도 같은 결과가 나오는 것을 보면 인터넷 익스플로러의 CSS해석 문제라고 생각합니다. 관련 정보 아시는 분들의 제보를 기다립니다.

일단 마치며

간단히 이미지 정렬하는 방법에 대해 포스팅할 생각이었는데 p 태그에 테두리를 설정한 순간 이미 간단함은 멀리 사라졌습니다. 물론 이렇게 보여드리기 위한 예가 아니라면 흔히 발생하는 문제는 아닐겁니다. 하지만 글을 쓰는 입장에서는 가능하다면 왜 그런지 설명을 해야한다고 생각하기 때문에 간단하게 쓸 수가 없네요. 개인적으로 긴 글을 아주 싫어해서 나머지는 다음 글에서 이어나가기로 하겠습니다. ^^;

자료를 찾아보며 알게 된 분명한 사실은 인터넷 익스플로러가 표준을 따르는 오페라, 파이어폭스, 사파리(윈도우즈용으로 테스트)와는 다른 방식으로 float을 처리한다는 사실입니다. 이는 인터넷 익스플로러가 사용하는 자체 속성인haslayout과 관련이 있는데 다음 글에서 좀 더 자세히 알아보도록 하겠습니다. 아울러 overflow를 사용하는 float제거 방법과 그 외의 방법도 소개하겠습니다.

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


출처 - http://blog.wystan.net/2007/08/11/image-alignment-with-css





'Development > CSS' 카테고리의 다른 글

css 수직 정렬  (0) 2012.12.24
css - div 에서 text 수직 정렬 시키기  (0) 2012.06.28
css - navigation bar  (0) 2012.06.26
CSS를 이용한 마우스 커서 모양 지정  (0) 2012.06.14
CSS - font 설정  (1) 2012.06.10
Posted by linuxism
,


▶ DIV, SPAN, FIELDSET 공통점
  - 특별한 태그 속성이 없음
  - 쓰이는 style속성은 동일. 
  - style속성에 따라 형태가 달라짐
  - 태그내에 속성을 적지 않아도 시작태그와 마감태그 사이에 들어가는 내용에 따라 그 공간의 크기도 자동으로 결정


▶ DIV, SPAN, FIELDSET 다른점
  DIV             - 태그의 시작 전후에 자동으로 줄바꿈 기능 
  SPAN          - 태그의 시작 전후에 자동 줄바꿈 기능 없음. 이웃으로 위치.
  FIELDSET    - DIV, SPAN태그와 달리 테두리 존재. 모서리 부분이 둥근것이 특징.
                    - FIELDSET 태그 하위로 제목 추가 가능 (ex. <LEGEND align="left | right | center">제목</LEGEND>)
                    - 태그의 시작 전후에 자동으로 줄바꿈 기능 존재


▶ 중요 style 정리
 * width, height 
    - 크기 결정 속성
    - DIV, SPAN, FIELDSET은 style속성내의 width, height 속성을 통해서만 크기 결정 가능
    - 숫자와 단위(px, pt, cm, %, etc) 동시 사용하여 크기 결정, 단위 사용하지 않으면 px로 인식
    - 사용법
       <DIV style="width: 100px; height: 300px">내용</DIV>
       <SPAN style="width: 200; height: 200">내용</SPAN>
       <FIELDSET style="width: 100%; height: 100%">내용</FIELDSET>


 * background
    - 배경 결정 속성
    - 색상 또는 이미지 주소 사용 가능
    - 사용법 
       * 색상인 경우 
         <DIV style="background: 색상">내용</DIV>
         <SPAN style="background: 색상">내용</SPAN>  
         <FIELDSET style="background: 색상">내용</FIELDSET>
       * 이미지인 경우 
         <DIV style="background: url('이미지 주소')">내용</DIV>
         <SPAN style="background: url('이미지 주소')">내용</SPAN>
         <FIELDSET style="background: url('이미지 주소')">내용</FIELDSET>
 
 * border         
    - 테두리 결정 속성
    - 테두리 두께, 형태(8가지), 색상 사용
    - 형태는 필수, 나머지는 생략 가능
    - 형태의 종류 : dotted, dashed, solid, double, groove, ridge, inset, outset 
    - 사용법 
       <DIV style="border: 1 solid #ff0000">내용</DIV>
       <SPAN style="border: 5 dotted #ff0000">내용</SPAN>
       <FIELDSET style="border: 10 double #ff0000">내용</FIELDSET>
 
 * padding 
    - 경계에서 내용까지의 여백 결정 속성
    - 상, 우, 하, 좌 의 여백의 크기(0을 포함한 양의정수)로 사용
    - 사용법
       <DIV style="padding: 10">내용</DIV> (외곽 경계에서 상·우·하·좌 : 10px 여백생성)
    <DIV style="padding: 10 20">내용</DIV> (외곽 경계에서 상·하 : 10px, 우·좌 : 20px 여백생성)
       <SPAN style="padding: 10 20 30">내용</SPAN> (외곽 경계에서 상 : 10px, 우·좌 : 20px, 하 : 30px 여백생성)
       <FIELDSET style="padding: 1 2 3 4">내용<FIELDSET> (외곽 경계에서 상 : 1px, 우 : 2px, 하 : 3px, 좌 : 4px 여백생성)


 * margin
    - 위치 결정 속성
    - padding은 외각 경계에서 여백을 통해 내용의 위치가 바뀌지만 margin은 DIV, SPAN, FIELDSET 자체의 위치 변경
    - 상, 우, 하, 좌 의 크기(정수) 사용
    - 사용법 
       <DIV style="margin: 10">내용</DIV> (외곽 경계가 상·우·하·좌 : 10px 위치이동)
       <DIV style="margin: 10 20">내용</DIV> (외곽 경계가 상·하 :10px, 우·좌 : 20px 위치이동)
       <SPAN style="margin: -10 20 30">내용</SPAN> (외곽 경계가 상 : -10px, 우·좌 : 20px, 하 : 30px 위치이동)
       <FIELDSET style="margin: 1 2 3 -4">내용<FIELDSET> (외곽 경계가 상 : 1px, 우 : 2px, 하 : 3px, 좌 : -4px 위치이동)


 * overflow
    - 영역 내 스크롤 생성 결정 속성
    - overflow를 사용하지 않는다면 내용물의 크기에 맞게 영역의 크기가 늘어남
    - 요소 종류 : auto, hidden, scroll
       auto : 내용물의 크기가 큰 경우에만 스크롤바 생성
       hidden : 지정된 크기 이외의 부분은 보여지지 않음
       scroll : 내용물의 크기와는 상관없이 스크롤바 생성
    - 사용법 
       <Div style="overflow: auto">내용</DIV>
       <SPAN style="overflow: hidden">내용</SPAN>
       <FIELDSET style="overfloe: scroll">내용</FIELDSET>
 
 * font 
    - 글자 스타일 결정 속성
    - 글씨형태, 글씨의 크기/줄간격, 글씨체 지정 가능
    - 글씨형태 : bold(두껍게), italic(기울임)등..
    - 글씨의 크기 단위 : pt, 1pt부터 사용가능
    - 글씨의 줄간격 : pt의 단위나 글씨의 크기에 비례하여 사용 가능
    - 글씨체 : 각 개인 컴퓨터에 설치된 글꼴 이름 (굴림체, 돋움체, 바탕체 etc..)
    - 사용법 
       <DIV style="font: bold 9pt/1.3 돋움">내용</DIV> (두껍게 글씨크기:9pt 줄간격:9*1.3pt 글씨체:돋움)
       <SPAN style="font: italic 12pt/15pt 굴림체">내용</SPAN>(기울여서 글씨크기:12pt 줄간격:15pt 글씨체:굴림체)
       <FIELDSET style="font: normal 15pt/2 바탕체">내용</FIELDSET>(글씨크기:15pt 줄간격:15*2pt 글씨체:바탕체)
       (normal일 경우 적지 않아도 무방)


 * color
    - 글자의 색상을 결정
    - 영문으로 된 색상명 또는 RGB코드 사용
    - 사용법 
       <DIV style="color: #ff0000">내용</DIV> 
       <SPAN style="color: skyblue">내용</SPAN>
       <FIELDSET style="color: gold">내용</FIELDSET>


 * display 
    - 영역의 숨김, 보여짐 여부 결정
    - none, block, inline 속성으로 결정됨
    - none : 숨김
    - block : 보여짐(다른줄에 보여짐)
    - inline : 보여짐(같은줄에 보여짐) 
    - default는 inline임
    - 사용법 
       <DIV style="display:inline">내용</DIV> 
       <SPAN style="display:block">내용</SPAN>
       <FIELDSET style="display:none">내용</FIELDSET> 


출처 - http://biju.tistory.com/284

'Development > HTML' 카테고리의 다른 글

html - 조건부 주석  (0) 2012.09.11
html - HTML 특수문자코드표  (0) 2012.08.01
HTML - select 디자인  (0) 2012.06.09
HTML - select  (0) 2012.06.09
html - viewport  (0) 2012.05.28
Posted by linuxism
,



CSS Navigation Bar.

본문 건너 뛰기

최근 저희 팀에서는 ProjectXE 라는 것을 준비하고 있습니다. 이슈트래커 또는 버그 트래킹 시스템이라고 불리우는 종류의 프로그램이죠. 현재 issuetrackerXE 라는 이름으로 배포되고 있는 모듈의 기능과 디자인을 조금 더 개선시킨 패키지 버전이라고 볼 수 있습니다. 제가 직접 기획도 했으니까 나중에 배포가 시작되면 피드백도 부탁드려야 겠네요.

이번에는 운이 좋게도 디자인팀으로부터 지원을 받았는데요. 이렇게 디자인팀으로부터 지원을 받은 디자인은 품질이 상당히 좋아서 한 번 쓰고 말기에는 정말 아깝더라구요. 재 활용 가치가 있는 UI 콤포넌트는 가끔 처음부터 재 사용을 염두해 두고 설계를 합니다. 물론 시간이 무척 오래 걸리는 단점은 있지만 다른 누군가의 시간을 분명히 단축해 줄꺼라 믿고 있습니다.

오늘 공유해 드릴 UI 콤포넌트는 평범한 네비게이션 바 입니다. 이런 종류의 네비게이션은 너무 흔해서 일년에 열두번도 더 코딩을 하지만 항상 재 사용을 염두하지는 않았기 때문에 할 때마다 새로 만들고 처음부터 다르게 코딩 합니다. 물론 디자인이 조금씩 달라지는 것도 이유가 있겠지만 다소 소모적인 부분이 있었던 것도 사실입니다. 보기에 평범해 보이지만 재 사용과 보편적 설계를 위해서 제가 이 네비게이션 바에 얼마나 많은 정성을 쏟았는지 한 번 설명드려 보겠습니다.

CSS Navigation Bar. 새 창으로 보기

보편적이고 사용성이 좋은

수평 네비게이션은 보편적인 형태지만 하위 메뉴를 처리하는 방법에는 크게 두 가지 형태가 있습니다. 하위 메뉴를 수평으로 늘어뜨리거나 또는 위 예제와 같이 수직으로 늘어뜨리거나. 그런데 이 두 가지 형태의 메뉴 구조는 사용성이 크게 다릅니다. 하위 메뉴를 수직으로 늘어뜨리는 것이 사용성과 확장성이 훨씬 좋습니다.

하위 메뉴를 수평으로 열게 되면 사용자는 정확하게 선택하기 위하여 ‘L’자 모양으로 마우스 포인터를 이동시켜야 합니다. 게다가 하위 메뉴 영역을 벗어날 때 하위 메뉴가 사라지도록 처리하는 경우 사용성은 더 나빠집니다. 원하는 메뉴 링크까지 이동하려면 조심스럽게 마우스 포인터를 옮겨야 하니까요. 하위 메뉴를 수직으로 펼치면 마우스의 이동 괘적은 ‘I’자 모양을 그리게 되고 마우스를 옮기는 과정에서 메뉴가 닫힐 위험은 사라집니다. 

웹 표준과 접근성을 지키는

이런 메뉴 구조를 테이블 <table> 요소를 사용해서 마크업하면 의미에도 맞지 않고 접근성도 떨어집니다. 네비게이션 요소는 HTML로 표현할 때 ‘목록’ 요소 <ul>, <li>로 마크업 해야 합니다. 동등한 수준의 내용이 같은 계층에서 여러번 반복 된다면 ‘목록’입니다. 시각장애인이 사용하는 화면 낭독기는 이런 목록에 대하여 목록의 ‘시작, 끝, 단계 그리고 항목의 개수’를 음성으로 알림으로써 목록에 대한 이해를 돕습니다. 상기 예제에서 ‘CSS X’ 버튼을 누르면 네비게이션이 어떤 HTML 구조로 마크업 되어 있는지 확인할 수 있습니다. 이렇게 코딩된 네비게이션 바는 다음과 같은 장점을 갖습니다.

  • 상-하위 계층 관계가 논리적으로 처리되어 CSS를 지원하지 않거나 걷어낸 장치(예:모바일)에서도 이해하기 쉽습니다.
  • 모든 항목에 키보드 접근이 가능하고 키보드 접근 순서가 의미있게 처리되어 있습니다.

이 네비게이션 바는 키보드만을 사용할 수 밖에 없는 시각장애인과 지체장애인도 사용할 수 있습니다. 키보드만으로 탐색을 시도해 보세요.

유연하고 확장하기 좋은

하위 메뉴의 개수가 상당히 많이 늘어나는 상황에서 수평으로 열리는 하위 메뉴는 필연적으로 줄바꿈을 동반하거나 메뉴의 개수를 제한하게 되지만 수직으로 열리는 메뉴는 그럴 필요가 없기 때문에 메뉴 데이터가 가변적인 상황에서 확장성이 더 좋습니다.

메뉴의 전체적인 너비는 레이아웃에 맞게 가변폭으로 조절되고 메뉴 항목의 너비도 메뉴 이름의 길이에 따라 모두 가변폭으로 처리되어 있습니다. 디자인 때문에 글자 개수를 자르거나 제한 할 필요가 없습니다.

네비게이션 바의 색상을 바꾸기 위해 새로 이미지를 컷팅할 필요가 없습니다. CSS 편집을 통해 배경색과 보더 색상만 변경해 주면 끝입니다. 은은하게 처리된 그라디언트 효과는 배경색상 위에 반투명 흰색 그라디언트 PNG 이미지를 덧붙이는 기법으로 처리 했습니다.

이미 널리 쓰이고 있는

jQuery 자바스크립트 프레임웍을 사용했기 때문에 약간의 자바스크립트 코드를 추가하거나 변형하면 누구나 쉽게 사용할 수 있습니다. 물론 지금 그대로 사용해도 될만큼 이미 스크립트가 잘 처리되어 있습니다. 자바스크립트는 행복한고니에 의해 처리 되었습니다.

브라우저 호환성

다음과 같은 브라우저에서 테스트 되었고 호환성이 확보되어 있습니다.

  • Internet Explorer 6
  • Internet Explorer 7
  • Internet Explorer 8
  • Firefox 3
  • Chrome 4
  • Safari 4
  • Opera 10

이 네비게이션을 처리하기 위하여 테스트 했던 거의 모든 브라우저들의 버그를 다 만났던것 같습니다. 여러분이 보시기에 HTML 코드에 ‘이건 왜 이렇게 마크업을 했지?’ 라고 의문이 든다면 그 부분이 바로 그 흔적 입니다. 특히 IE7 브라우저의 경우 링크 영역(width)을 제대로 렌더링하지 못하는 버그 때문에 상당히 고전을 했는데 결국 방법을 찾지 못하고 자바스크립트의 도움을 받아서 디버깅 했습니다. 코딩하는데 1.5일이 걸렸고 디버깅하는 시간도 1.5일이나 걸렸습니다. 3일동안 쳐다보고 있으니 아주 지겨워 죽겠더라구요.

이 밖에 더 많은 예제들이 OUIF | XEUI 페이지에 링크되어 있습니다.

분류: CSS,XE,웹 기획,웹 디자인,웹 접근성,웹 표준,자바스크립트 | 2010년 2월 11일, 0:38 | 정찬명 | 댓글: 98개 | 
트랙백URI - http://naradesign.net/wp/2010/02/11/1185/trackback/


출처 - http://naradesign.net/wp/2010/02/11/1185/


===================================================================================


CSS Vertical Navigation Bar.

본문 건너 뛰기

얼마 전 공유했던 ‘CSS Navigation Bar‘는 ‘수평+서브메뉴 드롭다운’ 네비게이션 이었는데요. 오늘 공유하는 것은 ‘수직+서브메뉴 드롭다운’ 네비게이션 입니다. 수평 메뉴보다 수직 메뉴가 모든 면(HTML/CSS/JS)에서 코드가 더 간결하고 만들기도 쉽네요.

특징

  • 중첩 목록(ul>li>ul>li) 구조로 마크업 했습니다.
  • 키보드만으로도 조작이 가능하고 키보드의 접근 순서는 논리적으로 처리되어 있습니다.
  • 서브메뉴 토글에 jQuery의 .slideDown() 및 .slideUp() 효과를 사용 했습니다.
  • 이미지를 한 번 사용 했습니다.

유의사항

간혹 이런 수직 메뉴의 서브 메뉴 펼침 동작을 onmouseover 이벤트 헨들러로 처리하는 경우가 있는데요. 그런 경우 사용성이나 접근성이 정말 나빠집니다. 

사용성이 나빠지는 이유는 아래쪽에 있는 메뉴를 선택하기 위하여 링크 위를 onmouseover 하는 순간 해당 링크의 서브 메뉴가 펼쳐지는데 이는 보통 원치 않는 동작이기 때문입니다. 

접근성이 나빠지는 이유는 마우스와 동등하게 키보드가 접근할 수 있도록 onmouseover 헨들러와 onfocus 헨들러를 병행해서 작성하지 않는 경우 입니다. 이런 경우 키보드가 서브 메뉴를 펼칠 수 없기 때문에 키보드 사용자는 서브 메뉴에 접근할 수 없습니다. onmouseover 헨들러를 사용했다면 반드시 onfocus 헨들러를 병행 작성하여 동등한 기능을 처리할 수 있도록 해야 합니다.

따라서 수직 메뉴를 드롭다운 형태로 열고 닫는 오늘의 예제와 같은 경우 onmouseover 이벤트 헨들러 사용은 절대적으로 피하는 것이 좋고 onmouseover 이벤트 헨들러 사용은 보편적인 다른 모든 경우에도 최소화 하는 것이 좋습니다.

이 밖에 더 많은 예제들이 OUIF | XEUI 페이지에 링크되어 있습니다.

분류: CSS,웹 디자인,웹 접근성,웹 표준,자바스크립트 | 2010년 3월 10일, 22:15 | 정찬명 | 댓글: 44개 | 


출처 - http://naradesign.net/wp/2010/03/10/1212/










Posted by linuxism
,