Showing posts with label 웹 표준. Show all posts
Showing posts with label 웹 표준. Show all posts

2010-08-08

HTML 텍스트 태그

단락을 구성하는 텍스트 중에서 특정 부분만을 다르게 표현해야 하는 경우가 있다. 이 때 의도와 결과(웹 브라우저에 표시되는 모습)를 구분하고 초점을 결과가 아닌 의도에 맞추어야 한다. 강조하기 위해서 진하게 표현하는 것일 뿐 진하게 표현하는 것 자체는 중요하지 않다.


XHTML에는 의도를 명시하기 위한 텍스트 태그와 표현을 위한 텍스트 태그가 있다.


의도를 명시하기 위한 태그는 다음과 같다.

  • abbr - 약어
  • acronym - 두문자어
  • cite - 인용 출처
  • code - 프로그램 소스 코드(컴퓨터 관련 문서와 매뉴얼에서 주로 사용)
  • dfn - 용어나 경구
  • em - 강조
  • kbd - 사용자가 (키보드로) 입력하는 명령어(컴퓨터 관련 문서와 매뉴얼에서 주로 사용)
  • q - 인용글
  • samp - 텍스트로 표시되는 프로그램 실행 결과(컴퓨터 관련 문서와 매뉴얼에서 주로 사용)
  • strong - 매우 강조
  • var - 변수(컴퓨터 관련 문서와 매뉴얼에서 주로 사용)


표현을 위한 텍스트 태그는 다음과 같다.


  • b - 진하게(bold)
  • i - 기울이기(italic)
  • big - 크게(larger)
  • small - 작게(smaller)
  • tt - 모노스페이스 폰트로 표시하기(monospaced, teletypewriter)
  • sup - 텍스트를 위에 기입하기(어깨글자, superscripted)
  • sub - 텍스트를 아래에 기입하기(subscripted)


sup와 sub 태그를 제외한 표현을 위한 텍스트 태그는 사용하지 않는 것을 권장한다.


XHTML에서 삭제된 표현을 위한 태그들도 있다.

  • blink - 텍스트 깜빡이기
  • strike - 가운데 줄 긋기
  • s - strike와 동일
  • u - 밑줄 긋기
  • basefont - 페이지 전체 글꼴 설정
  • font - 글꼴 설정

cite와 q

q 태그는 인용하는 내용 자체를 명시하는데 사용하고, cite 태그는 출처를 명시하는데 사용한다.

홍세화 기자는 한겨레 신문에 기고한 <cite>의식과 정서</cite> 칼럼에서 정운찬 전 총리에 대해 <q>애당초 그의 정서는 불관용으로 악착스런 이 정권에 어울리지 않았다. 그러나 그는 권좌의 길을 택했다. 후배와 제자들의 끈질긴 만류가 있었지만 소용없었다. 그에게서 학문적 심지로서는 유약한 대신 “우리가 나라를 이끄는 주역이다”라는 주장 뒤에 숨어 있는 권좌에 대한 친화력에서는 무척 강한 한국 사회 엘리트의 자화상을 확인한다는 것은 즐거운 일이 아니다.</q>라고 평가하고 있다.

abbr과 acronym

두 태그를 나타내는 단어 abbreviation과 acronym을 모두 약어로 번역하면 차이가 명확하지 않지만, acronym을 두문자로 번역하면 그 차이를 쉽게 알 수 있다. abbr 태그는 한단어를 줄여 쓴 경우에 사용하고, acronym은 여러 단어의 앞 글자만을 대문자로 이어 표기한 경우에 사용한다.

  • abbr - Jan.(January), Mr(Mister), Ltd.(Limited), ad(advertisement), exam(examination)
  • acronym - CEO(Chief Executive Officer), BBC(British Broadcasting Corporation), DOS(Disk Operating System)

2010-04-26

서평 - 웹 폼

웹 폼(Web Form)에 대한 Web Form Design: Filling in the BlanksForms that Work: Designing Web Forms for Usability에 대한 서평이다.


웹 폼에 대한 책을 쓸 생각을 하다니... 제한적인 소재 때문인지 두 책 모두 200페이지 정도로 읽기에 부담이 없다. 창조적이지는 않지만 애플리케이션을 개발하면서 한번쯤 고민하거나 해야할 내용들을 잘 정리해 두었다.

당연하게 생각되는 내용들이 많지만 그건 책을 읽었기 때문일 게다. 이 두 책은 애플리케이션을 개발하면서 당면할 소소한 문제들을 해결하기 위해 투자해야 하는 시간을 크게 줄여주는 미덕이 있다.


이 책은 같은 주제를 다루지만 차이가 있다.  첫번째 책은 How(구현이 아닌 디자인 측면에서)에, 두번째 책은 Why에 방점이 찍혀있다. 따라서 두 책을 모두 읽는 것이 도움이 될 듯 싶다.

2010-04-12

자바스크립트 - 문자열 앞뒤 여백 제거

Even Faster Web Sites를 보면 문자열 앞뒤 여백을 제거하는 자바스크립트 함수를 최적화하는 방법이 나온다.

먼저 가장 간단한 방법이다. 정규 표현식으로 문자열 앞뒤 여백을 제거한다.

function trim(text) {
    return text.replace(/^\s+|\s+$/g, "");
}


다음과 같이 정규 표현식에서 g 옵션을 제거하면 성능을 개선할 수 있다.

function trim(text) {
    return text.replace(/^\s+/, "").replace(/\s+$/, "");
}


문자열 뒤에 있는 여백을 정규 표현식을 사용하지 않고 처리하면 성능을 더욱 개선할 수 있다.

function trim(text) {
    text = text.replace(/^\s+/. "");
    for (var i = text.length - 1; i >= 0; i--) {
        if (/\S/.test(text.charAt(i))) {
            text = text.substring(0, i + 1);
            break;
        }
    }
    return text;
}


어떤 방법이 어떤 방법보다 항상 올바른 것은 아니다. 마지막 방법은 성능이라는 장점을 갖지만 변태들을 위한 방법일 수 있다. 첫번째 방법은 간결하지만 성능이 중요한 부분에 사용하기에는 적합하지 않다.


Prototype은 두번째 방법(String#strip)을 사용한다.

function strip() {
    return this.replace(/^\s+/, '').replace(/\s+$/, '');
}



2010-04-11

AJAX와 뒤로 가기 버튼

AJAX 혹은 DHTML을 사용할 때 뒤로 가기 버튼을 구현하는 방법이다.

Prototype 라이브러리
를 사용했다.


var Executer = Class.create({
  start: function() {
    new PeriodicalExecuter(function(pe) {
      if (!document.location.hash) {
        return;
      }
      var hash = document.location.hash.replace("#", "");
      if (hash == Executer.hash) {
        return;
      }
      Executer.hash = hash;
      if (hash.startsWith("menu")) {
        Menus.click(hash.substring(5));
     } else if (hash.startsWith("link")) {
        ...
     }
    }, 0.5);
  },
  execute: function(category, id) {
    window.location.href = "#" + category + "/" + id;
  }
});

사용 방법은 다음과 같다.

// onload 등을 이용해서 페이지 초기화시에 Executer 객체를 생성한 후에 start 메소드를 호출한다.

executer = new Executer();
executer.start();

뒤로 가기 기능을 제공해야 하는 경우 다음과 같이 처리한다.
<a href="#" onclick="executer.execute('menu', server/database'); return false;" >...</a>


동작 방법은 단순한다. 사용자가 뒤로 가기 기능이 필요한 행위를 할 때마다 window.location.href를 이용해서 url에 (#고유값)를 붙여준다. 이 경우에 화면이 변경되지지 않지만 웹 브라우저 경로창 URL과 히스토리 정보는 변경된다.

* IE 6에서는 안된다고 함. 이 경우에는 iframe을 사용하는 방법이 있다고 함.

그리고 백그라운드에서 주기적으로 스케줄러(여기서는 PeriodicalExecuter를 사용했는데, setInterval과 동일하다.)가 동작하면서 document.location.hash 값을 체크하여 변경이 있으면 변경 내용에 맞는 작업을 수행해준다.

* 스케줄러 호출 주기가 짧기 때문에 사용자는 거의 실시간 반응하는 것으로 느끼게 된다.

결국 사용자가 뒤로 가기 버튼을 눌러도 실제 어떤 작업이 이루어지는 것은 아니고 document.location.hash 값만 변경될 뿐이다. 물론 스케줄러가 변경 값을 확인하여 필요한 작업을 수행하게 된다.

hash 값에 따른 처리 코드는 상황에 맞게 수정해 주어야 한다. 여기서는 category를 이용해서 범주를 구분했다.



다음 내용을 참고했다.

Fixing the Back Button and Enabling Bookmarking for AJAX Apps

* 파이어폭스 3.6.3에서만 테스트를 했다.

2010-03-24

SMS 길이 체크하기

오늘 웹에서 SMS 전송 모듈을 작성했다.

  • 메시지 박스는 textarea로 구현한다.
  • SMS는 최대 80 바이트까지만 전송할 수 있다.
  • 사용자가 메시지 박스에 텍스트를 입력하면 실시간으로 하단에 텍스트 바이트 크기를 보여준다.

HTML 구조는 다음과 같다.

<div>
    <textarea id="text" rows="4" cols="30"></textarea>
    <br/>
    <span id="length"></span>
</div>


그리고 onkeydown(up, press) 이벤트로 바이트 크기를 체크하려는데 파이어폭스에서는 한글 입력에 대해서는 이 이벤트가 발행하지 않았다 ㅠㅠ


어쩔 수 없이 스케줄러(setInterval)로 백그라운드에서 바이트 크기를 처리하기로 했다. 약간의 딜레이를 감수하면서...

Prototype을 사용했다. 코드는 단순하지만 Prototype에 익숙하지 않으면 이해하기 쉽지 않다;;


우선 문자열 바이트 크기를 체크하는 함수를 String 클래스에 추가했다.

Object.extend(String.prototype, {bytes: function() {
    var source = this;
    var result = 0;
    for (var i = 0; i < source.length; i++) {
        result += (source.charCodeAt(i) > 128) ? 2 : 1;
    }
    return result;
}});

  • 기존 클래스에 메소드를 추가할 수 있다는 것이 자바 스크립트와 같은 언어의 장점이다.
  • Object.extend는 Prototype이 제공하는 메소드이다.
  • bytes라는 이름으로 메소드를 추가했다.

그리고 LengthChecker 클래스를 다음과 같이 작성했다.

var LengthChecker = Class.create({
    initialize: function(target, handler) {
        this.target = $(target);
        this.handler = handler;
    },
    apply: function() {
      this.target.observe("focus", this.start.bind(this));
      this.target.observe("change", this.stop.bind(this));
      this.target.observe("keydown", this.callback.bind(this));
    },
    start: function() {
        this.executer = new PeriodicalExecuter(this.callback.bind(this), 1);
    },
    stop: function() {
        this.executer.stop();
        this.callback();
    },
    callback: function() {
        this.handler($F(this.target).bytes());
    }
});

  • apply 메소드에서 observe 메소드로 target에 foucs, change, keydown 이벤트를 등록했다. focus에서 스케줄러를 시작하고, change 메소드에서 스케줄러를 정지한다. 한글이 아닌 경우에는 문제가 없기 때문에 keydown 이벤트도 등록하였다.
  • Protoype이 제공하는 PeriodicalExecuter는 setInterval을 이용한 스케줄러이다.


사용 방법은 다음과 같다.

new LengthChecker("text", function(length) {$("length").update(length);}).apply();


LengthChecker 클래스 생성자의 파라미터는 다음과 같다.

  • target: 대상 textarea 요소(혹은 id)
  • handler: 주기적으로 호출되는 함수. 이 함수의 첫번째 파라미터는 target에 입력한 텍스트의 바이트 크기이다.
LengthChecker 객체를 생성한 후 apply 메소드를 호출하면 백그라운드에서 바이트 크기 체크 작업이 이루어진다.

  • Prototype 라이브러리 PeriodicalExecuter는 최소 1초 단위로 반복된다. 딜레이를 최소화하려면 setInterval 함수를 사용하야 한다.

2010-03-17

CSS 초기화

Sitepoint에 올라온 The Right Frame of Mind: Applying the Lessons of CSS Frameworks에서 중요한 정보를 얻었다.

CSS 전문가인 Eric Meyer가 제안한 것으로 웹 브라우저마다 다른 CSS 속성 값을 일정하게 초기화하는 방법이다.

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center, dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}

body {
line-height: 1;
}

ol, ul {
list-style: none;
}

blockquote, q {
quotes: none;
}

/* remember to define focus styles! */

:focus {
outline: 0;
}

/* remember to highlight inserts somehow! */

ins {
text-decoration: none;
}

del {
text-decoration: line-through;
}

/* tables still need 'cellspacing="0"' in the markup */

table {
border-collapse: collapse;
border-spacing: 0;
}


2010-03-15

text-decoration

text-decoration 속성으로 텍스트 위, 아래, 가운데에 줄을 그을 수 있다.




blink로 텍스트가 깜빡이는 효과를 표현할 수 있다.



선은 color 속성으로 지정한 색상으로 표시된다. 다음과 같은 방법으로 선 색상과 텍스트 색상을 다르게 가져갈 수 있다.


<span style="color: blue; text-decoration: underline;"><span style="color: red;">CSS</span></span>

결과는 다음과 같다.


동일한 텍스트에 두 개 이상의 효과를 주려면 여러 개의 CSS 속성 값을 동시에 설정하면 된다.



2009-09-24

Prototype 라이브러리

Prototype 라이브러리 사용과 관련한 주의사항이다.


AJAX를 이용해서 화면 특정 영역을 업데이트하는 경우가 있다.

new Ajax.Updater("update_area", "/update.html");

이 때 화면에 포함된 자바 스크립트를 수행하려면 다음과 같이 한다.

new Ajax.Updater("update_area", "/update.html", {evalScripts: true});


그런데 이 경우 IE 6.0에서는 자바 스크립트를 주석처리하면 안된다.

아래 같이 하면 자바 스크립트가 실행되지 않는다.

<script type="text/javascript"><!--

--></script>

아래 같이 해야 자바 스크립트가 실행된다.

<script type="text/javascript">

</script>


또한 함수를 선언할 때는 다음과 같이 해야 한다.

<script type="text/javascript">
  processRequest = function() {
    ...
  }
</script>

이 때 다음과 같이 var를 붙여서도 안된다.

  var processRequest = function() {
   ...
  }

2009-09-13

[책] 웹 이후의 세계

김국현 씨가 쓴 웹 이후의 세계를 읽었다.

SasS에 대한 관심 때문에 우연하게 서점에서 접한 이 책을 구매했다.


현실계, 이상계, 환상계라는 세계 구분은 좀 뜬금없게 느껴지고, 그 맥락 속에서 서술되는 이야기들이 별로 와닿지 않는다. 아마도 뻔한 이야기라는 느낌이거나 너무 무게를 잡았다는 인상 때문일거다.

아마도 이 책을 구매한 이유가 정보에 대한 빠른 이해를 기대하는 것이었기 때문일 게다.


그래도 정보에 대한 빠른 이해에는 큰 도움이 되었다. 이 바닥에서 일하지만 IT 트랜드에 대한 무지함 혹은 무관심이 야기한 이해 부족을 조금이나마 해소할 수 있었으니깐...

  • SasS와 클라우드의 차이를 이해했다. 난 클라우드를 SasS의 또다른 이름 정도로 치부했는데...
  • 가상화는 워낙 무지한 분야라 읽기 전이나 후나 큰 차이는 없지만... 각론으로 들어가면 이견이 많을 것 같다. 물론 무지함이 관심없음에 기인하기 때문에 각론으로 파들어갈 일은 없겠지만^^
  • 그린 IT는 MB 때문에 무조건 정이 안간다. 궁극적으로 혐오가 망가트리는 건 대상이 아니라 나 자신이라는 게 다시 증명되었다.
  • RIA는 아마도 내 업무와 관련성이 많은 분야인데 플래시나 실버라이트가 가지고 있지 못한 장점을 자바가 가지고 있다고 생각한다. 플래시나 실버라이트로 제니퍼를 구현할 수 있었을까? 닷넷과 결합한 버전업되었다는 실버라이트는 모르겠지만 플래시로는 어림도 없다. 물론 자바 FX는 나도 모른다.
  • 디지털 미디어나 모바일과 관련한 논의가 어떤 이슈를 중심으로 일어나고 있고, 어떤 문제점들이 있으며, 대안들에는 어떤 것들이 있을까를 잘 이해할 수 있었다. 핸드폰을 사용하기 시작한게 3년도 안된 나로서는 도움이 많이 되었다.
  • 제 3장 웹 주의 선언도 각론에서는 이견이 있겠지만 큰 맥락은 100% 동의한다. 하지만 나의 독서 필요성에서는 조금 벗어나 있다.


결론적으로 뜬금없어도 좋은 책이다.

2009-08-30

display: block과 inline

아래 태그는

<div>div1</div>
<div>dIv2</div>
<div>div3</div>

웹 브라우저에 아래와 같이 표시된다.
반면에 아래 태그는

<span>span1</span>
<span>span2</span>
<span>span3</span>

웹 브라우저에 아래와 같이 표시된다.

이 둘 사이에 나타나는 가장 큰 차이는 줄 바꿈 여부이다. div 태그는 줄바꿈되고, span 태그는 줄바꿈되지 않는다.

div 태그가 줄바꿈되는 이유는 CSS display 속성 기본 값이 block이기 때문이고, span 태그가 줄바꿈되지 않는 이유는 CSS display 속성 기본 값이 inline이기 때문이다.


아래처럼 반대로 설정하면

div {
  display: inline;
}

span {
  display: block;
}

웹 브라우저에 아래와 같이 표시된다.

block과 inline의 차이점은 줄바꿈만은 아니다.
  • block으로 설정하면 줄바꿈 되고, inline으로 설정하면 줄바꿈이 되지 않는다.
  • block으로 설정하면 상/하 margin과 padding 속성을 사용할 수 있지만, inline으로 설정하면 상/하 margin과 padding 속성을 사용할 수 없다.
  • block으로 설정하면 width, height 속성을 사용할 수 있지만, inline으로 설정하면 width, height 속성을 사용할 수 없다.

2009-08-28

드래그 앤 드랍

드래그 앤 드랍을 자바 스크립트로 구현하는 예제이다.

<div>드래그 앤 드랍</div>

위의 div 태그를 드래그 앤 드랍하려면 우선 onmousedown 속성을 설정한다.

<div onmousedown="drag(this, event);">드래그 앤 드랍</div>

사용자가 div 태그를 마우스로 누른 순간에 onmousedown 속성으로 선언한 자바 스크립트 함수(drag - 아래에서 설명)가 수행된다.

drag 함수는 다음과 같다.

/*
drag 함수의 첫번째 파라미터(element)는 드래그할 대상이고, 두번째 파라미터(event)는 이벤트이다.
*/


function drag(element, ev) {
}


다음은 drag 함수 구현부이다. 우선 마우스 커서를 드래그를 의미하는 것으로 변경한다.

document.body.style.cursor = "move";

/*
마우스 커서는 드래그할 대상(<div>드래그 앤 드랍</div>)이 아닌 body에 설정해야 한다. 마우스를 드래그를 하면 마우스 포인터가 대상 밖으로 벗어나는 것이 일반적이기 때문이다.
*/


그리고 document에 대해서 onmousemove 이벤트 리스너를 설정한다.

/*
onmousemove로 설정한 함수는 마우스가 움직일 때마다 반복적으로 계속 호출된다.  마우스 커서와 동일한 이유로 드래그할 대상(<div>드래그 앤 드랍</div>)이 아닌 document에 대해서 onmousemove 이벤트 리스너를 등록한다.
*/

document.onmousemove = function(ev) {
    // IE 6.0은 해당 함수 파라미터로 이벤트 객체를 전달하지 않는다.
    // 대신 window.event 변수로 전달한다.
    ev = ev || window.event;

    // prototype이 제공하는 API로 현재 마우스 커서의 위치 값을 추출한다.
    var top = Event.pointerY(ev);
    var left = Event.pointerX(ev);

    // 드래그할 대상을 움직이게 하려면 onmousemove 이벤트 리스너가 호출될 때마다
    // CSS 속성으로 위치 값을 변경한다.
    // position 속성을 absolute로 설정하고 left와 top 속성으로 위치를 지정한다.
    element.style.position = "absolute";
   element.style.left = left + "px";
   element.style.top = top + "px";
    // left, top 속성을 설정할 때 px(단위)를 명기해야 한다.

    // prototype이 제공하는 API로 이벤트를 종료하고 false를 반환한다. 그렇지 않으면
    // 주변에 있는 텍스트를 선택하는 것과 같은 현상이 일어난다.
    Event.stop(ev);
    return false;
  };

마우스 커서 위치 값 추출에 Prototype 라이브러리를 사용했다. 자세한 사항은 다음을 참조한다.


그리고 document에 대해서 onmouseup 이벤트 리스너를 설정한다.

/*
onmouseup으로 설정한 함수는 마우스 누른 것을 해제할 때(드랍) 호출된다. 마우스 커서와 동일한 이유로 드래그할 대상(<div>드래그 앤 드랍</div>)이 아닌 document에 대해서 onmousemove 이벤트 리스너를 등록한다.
*/

document.onmouseup = function(ev) {
    ev = ev || window.event;
    // 마우스 커서를 초기화한다.
    document.body.style.cursor = "auto";
   
   // 여기에서 필요한 작업을 한다. 이는 드래그 앤 드랍 성격에 따라서 달라진다.
   // 예를 들어, AJAX를 이용해서 현재 위치 값을 서버에 저장할 수도 있다.

    // 드래그앤 드랍과 관련한 이벤트 리스너를 초기화한다.
    document.onmousemove = null;
    document.onmouseup = null;
    Event.stop(ev);
    return false;
  };


최종적인 drag 함수는 다음과 같다.

function drag(element, ev) {
  document.body.style.cursor = "move";

  document.onmousemove = function(ev) {
    ev = ev || window.event;
    var top = Event.pointerY(ev);
    var left = Event.pointerX(ev);
    element.style.position = "absolute";
    element.style.left = left + "px";
    element.style.top = top + "px";
    Event.stop(ev);
    return false;
  };

  document.onmouseup = function(ev) {
    ev = ev || window.event;
    document.body.style.cursor = "auto";

    // 필요한 작업 수행

    document.onmousemove = null;
    document.onmouseup = null;
    Event.stop(ev);
    return false;
  };
  Event.stop(ev);
  return false;
}


2009-08-25

탭 메뉴 작성

CSS와 ul/li 태그로 탭 메뉴를 작성하는 방법이다.


기본 설정

XHTML 1.0을 준수하여 ul, li 태그로 아래처럼 작성한다.

<ul>
  <li><span>소프트웨어</span></li>
  <li><span>하드웨어</span></li>
  <li><span>네트워크</span></li>
</ul>

웹 브라우저에 아래처럼 표시된다.


탭 메뉴 1

CSS를 이용해서 ul, li 태그의 margin과 padding 값을 조정한다. 그리고 ul 태그의 list-style 속성 값을 none으로 한다.

ul {
  list-style: none;
  margin: 2em 1em;
  padding: 0;
}

li {
  margin: 0;
  padding: 1em 0.5em;
}

웹 브라우저에 아래처럼 표시된다.

li 태그의 display 속성 값을 inline으로 한다.

li {
  display: inline;
  margin: 0;
  padding: 1em 0.5em;
}


웹 브라우저에 아래처럼 표시된다.

li 태그에 border 속성을 준다.

li {
  border-bottom: 1px solid rgb(192, 192, 192);
  display: inline;
  margin: 0;
  padding: 1em 0.5em;
}


MS IE 6.0의 버그로 인해서 ul 태그 아래에 다른 태그가 없으면 선이 나타나지 않는다. 따라서 HTML을 아래처럼 수정한다.

<ul>
  <li><span>소프트웨어</span></li>
  <li><span>하드웨어</span></li>
  <li><span>네트워크</span></li>
</ul>

<div/>

 
모질라 파이어 폭스와 오페라에서는 아래 처럼 li 태그 사이에 간격이 생긴다.


이를 방지하기 위해서 아래처럼 li 태그 사이의 여백을 제거한다.
 
<ul>
  <li><span>소프트웨어</span></li
  ><li><span>하드웨어</span></li
  ><li><span>네트워크</span></li>
</ul>


선택한 탭 메뉴는 클래스 속성으로 표현한다.

<ul>
  <li><span>소프트웨어</span></li
  ><li class="selected"><span>하드웨어</span></li
  ><li><span>네트워크</span></li>
</ul>

아래와 같은 CSS 스타일을 추가한다.

li.selected {
  border: 1px solid rgb(192, 192, 192);
  border-bottom: none;
}

최종 결과는 아래와 같다.



탭 메뉴 2

배경 이미지를 이용해서 탭 메뉴를 수정한다.

앞의 예제에서 li 태그의 border 속성을 삭제하고 background 속성을 추가한다.

li {
  background: url("/resource/image/tab_off.gif") no-repeat;
  display: inline;
  margin: 0;
  padding: 1em 0.5em;
}

li.selected {
  background: url("/resource/image/tab_on.gif") no-repeat;
}


이미지를 이용했기 때문에 width 속성으로 넓이를 지정한다. 그리고 inline 요소는 넓이를 지정할 수 없기 때문에 display 속성을 삭제하고 float 속성의 값을 left로 지정한다. 그리고 좌우 padding 속성 값을 0으로 하고 텍스트를 가운데로 정렬한다.
 
li {
  background: url("/resource/image/tab_off.gif") no-repeat;
  float: left;
  margin: 0;
  padding: 1em 0;
  text-align: center;
  width: 78px;
}


2009-08-24

CSS 기본 설정

CSS 작성할 때 가장 먼저하는 것들이다.


웹 브라우저마다 다른 기본 값 초기화


block 유형 태그 기본 값이 웹 브라우저마다 다른 경우가 있다. 따라서 다음과 같이 border, margin, padding 등의 속성을 모두 0으로 설정한다.

html, body, form, ul, li, div, p, h1, h2, h3 {
  border: 0;
  margin: 0;
  padding: 0;
}

/*
html과 form에 대해서도 초기화를 해준다.
모든 태그를 초기화하지는 않고 실제로 사용할 태그들에 대해서만 초기화한다.
*/

예전에는 다음 방법을 사용한 적도 있는데 단점이 많았다.

* {
  border: 0;
  margin: 0;
  padding: 0;
}


이미지에 대한 외곽선 제거를 위한 설정

a img {
  border: 0;
}


테이블 작성

CSS와 HTML에 관심을 갖게된 계기가 table 목록이었다. 2003년 가을에 참여했던 프로젝트에서 웹 디자이너가 작성한 table 목록은 다음과 같았다.

  • table 태그 안에 table 태그를 넣고 첫번째 테이블 배경색으로 선을 표시한다.
  • 선과 글자 사이의 간격은 &nbsp;로 하는 것이었는데, 결과적으로 &nbsp;를 제대로 신경쓰지 않는 게으름이나 HTML 코드 상에서 태그와 글자 사이의 여백이나 줄 바꿈 등의 이유로 들죽날죽이었다.

그러다가 CSS padding 속성으로 이를 손쉽게 제어할 수 있다는 걸 알게 되면서 CSS와 HTML에 대한 관심을 가지게 되었다.



그 이후로 이런 저런 시행착오를 거쳐 지금 주로 사용하는 table 태그로 목록을 작성하는 간결한 방법은 다음과 같다. 우선 table 태그를 다음과 같이 작성한다.

<table>
  <thead>                       <!-- 목록 이름과 목록 내용을 thead와 tbody 태그로 명시적으로 구분 -->
    <tr>
      <th>Column 1</th>   <!-- 목록 이름에는 td 대신에 th 태그를 사용 -->
      <th>Column 2</th>
      <th>Column 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Content 11</td>
      <td>Content 12</td>
      <td>Content 13</td>
    </tr>
    <tr>
     <td>Content 21</td>
     <td>Content 22</td>
     <td>Content 23</td>
   </tr>
  </tbody>
</table>


지금까지 작업 내용을 웹 브라우저로 보면 다음과 같다.
th와 td 태그에 선을 설정한다.

th, td {
  border: 1px solid silver;
}

이러면 선은 표시되지만 셀과 셀 사이에 여백이 보인다.
이 셀과 셀 사이 여백은 다음과 같이 제거한다.

table {
  border-collapse: collapse;
}

그리고 답답함을 없애기 위해서 셀에 여백을 준다.

th, td {
  border: 1px solid silver;
  padding: 4px 5px;
}

문자열이 긴 경우에는 셀 안에서 줄 바꿈이 일어나기 때문에 line-height 보다는 padding 속성으로 상하 여백을 설정한다.


그리고 목록 이름에 대해서 배경색을 준다.

thead {
  background: navy;
  color: white;             /* 배경색을 설정하면 글자 색도 함께 지정하는 것이 일반적이다. */
}


다음은 최종적인 모습이다.
table01.html

다운로드 편의를 위해서 HTML에 CSS를 포함시켰다.

2009-07-15

웹 브라우저 버전 체크

클라이언트나 서버 프로그래밍에서 사용자 웹 브라우저 정보를 알아야 하는 경우가 있다. 이를 위한 방법이다.


자바 스크립트에서는 아래 함수를 사용한다.

function getBrowser() {
  var agent = navigator.userAgent;
  var result = "unknown";
  if (agent == null) {
  } else if (agent.indexOf("MSIE 6.0") > -1) {
    result = "ie6";
  } else if (agent.indexOf("MSIE 7.0") > -1) {
    result = "ie7";
  } else if (agent.indexOf("MSIE 8.0") > -1) {
    result = "ie8";
  } else if (agent.indexOf("Firefox") > -1) {
    result = "firefox";
  } else if (agent.indexOf("Opera") > -1) {
    result = "opera";
  } else if (agent.indexOf("Chrome") > -1) {
    result = "chrome";
  } else if (agent.indexOf("Safari") > -1) {
    result = "safari";
  }
  return result;
}


자바에서는 아래 메소드를 사용한다.

package com.dimdol.util;

import javax.servlet.http.HttpServletRequest;

public final class WebUtils {

  private WebUtils() {
  }

  public static String getBrowser(HttpServletRequest request) {
    String agent = request.getHeader("User-Agent");
    String result = "unknown";
    if (agent == null) {
    } else if (agent.indexOf("MSIE 6.0") > -1) {
      result = "ie6";
    } else if (agent.indexOf("MSIE 7.0") > -1) {
      result = "ie7";
    } else if (agent.indexOf("MSIE 8.0") > -1) {
      result = "ie8";
    } else if (agent.indexOf("Firefox") > -1) {
      result = "firefox";
    } else if (agent.indexOf("Opera") > -1) {
      result = "opera";
    } else if (agent.indexOf("Chrome") > -1) {
      result = "chrome";
    } else if (agent.indexOf("Safari") > -1) {
      result = "safari";
    }
    return result;
  }

}

Ruby on Rails에서는 아래 함수를 사용한다.

module ApplicationHelper

  def get_browser
    agent = request.env['HTTP_USER_AGENT']
    result = "unknown"
    if agent.nil?
    elsif agent.include?("MSIE 6.0")
      result = "ie6"
    elsif agent.include?("MSIE 7.0")
      result = "ie7"
    elsif agent.include?("MSIE 8.0")
      result = "ie8"
    elsif agent.include?("Firefox")
      result = "firefox"
    elsif agent.include?("Opera")
      result = "opera"
    elsif agent.include?("Chrome")
      result = "chrome"
    elsif agent.include?("Safari")
      result = "safari"
    end
    return result
  end

end


2008-12-19

display: none과 visibility: hidden

CSS에서 display 속성을 none으로 설정하는 것과 visibility 속성을 hidden으로 설정하는 것은 비슷하지만 명확한 차이가 있다.

다음 HTML이 있다.

<div id="one">One</div>
<div id="two">Two</div>
<div id="three">Three</div>

CSS 설정은 다음과 같다.

div {
  border: 1px solid silver;
  height: 15px;
  margin: 10px 0;
  text-align: center;
  width: 200px;
}

웹 브라우저에 아래와 같이 표시된다.


먼저 두번째 태그(two) display 속성을 none으로 설정하면

#two {
  display: none;
}

웹 브라우저에 아래와 같이 표시된다.


display 속성을 none으로 설정하면 해당 태그가 HTML 문서 상에 존재하지 않는 것과 같이 된다. 즉, 태그가 아래와 같다고 할 수 있다.

<div id="one">One</div>
<div id="three">Three</div>


반면에 두번째 태그(two) visibility 속성을 hidden으로 설정하면

#two {
  visibility: hidden;
}

웹 브라우저에 아래와 같이 표시된다.


visibility 속성을 hidden으로 설정하면 해당 태그 내용은 보이지 않지만 해당 태그가 차지하는 공간은 비워진채로 표시된다.

2006-07-07

웹 UI 가이드라인

1. 개요

HTML(Hyper Text Markup Language)과 CSS(Cascading Style Sheet)를 사용한 웹 UI 작성 가이드라인을 설명한다. 이 가이드라인은 HTML 코드의 최소화와 간결성 확보를 통한 웹 어플리케이션 개발 생산성과 유지 보수성 향상을 목표로 한다. 그리고 트래픽의 최소화를 통한 웹 어플리케이션 성능 향상도 목표로 한다.

또한 가능한 대중적으로 사용하는 브라우저(MS IE, 모질라 파이어폭스, 오페라, 사파리 등)에서 정상적으로 동작하는 HTML과 CSS를 작성하는 것을 목표로 한다.

이를 위해서 W3C 표준 기술을 중심으로 웹 UI를 작성하는 것을 권장한다. HTML은 XHTML 1.0을 기준으로 하고, CSS는 대중적으로 많이 사용하는 브라우저를 기준으로 한다. 단, 자세한 버전은 프로젝트와 어플리케이션의 상황에 맞게 조정한다.


2. 웹 표준 가이드

웹 표준과 관련해서 명심해야 하는 사항은 모든 브라우저에서 동일하게 보이도록 UI를 구성하는 것이 목표가 아니라는 점이다. 여기에 과도하게 집중하면 효과보다 큰 비용이 발생할 수 있다. 웹 표준를 통한 웹 UI의 작성의 목표는 모든 브라우저에서 사용자가 사용하는데 큰 불편함을 느끼지 않도록 하는 것이다.


3. HTML 작성 가이드라인

일반적인 HTML 작성 가이드라인은 아래와 같다.


(1) XHTML 사용

일반 HTML 4.0 보다 XML 표준을 준수하는 XHTML 1.0을 사용한다. 따라서 모든 HTML 문서는 아래처럼 시작해야 한다.

<?xml version="1.0" encoding="UTF-8"?> <!-- MS IE를 고려하여 삭제 -->

<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko" lang="ko">
</html>

단, XML 선언부가 있는 경우에 MS IE 6.0은 비표준 방식으로 UI를 표현함으로 이를 삭제하도록 한다.


그리고 XHTML 작성에 있어서 XML의 일반적인 작성 원칙을 준수한다.


DOCTYPE을 선언한다. 문서의 앞 부분에 DOCTYPE을 선언한다.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">


html 태그에 xmlns 속성을 기입한다.

<html xmlns="http://www.w3.org/1999/xhtml"></html>


소문자를 사용한다. XML은 대소문자를 구분하며 XHTML은 태그와 속성의 이름으로 소문자를 사용한다. 그리고 속성의 값도 소문자 사용을 기본으로 한다.

<table border="0">
   
</table>


속성 값은 큰 따옴표(Double Quatation) 안에 넣는다. 큰 따옴표 없이 속성에 대한 값을 지정하지 않는다.

<a href="http://www.doosan.com">Doosan</a>


속성에는 항상 값을 기입한다.

<hr noshade="noshade">


& 속성 값에 대해서 &amp;를 사용한다.

<a href="List.jsp?a=1&amp;b=2">


모든 태그는 닫는다.

<p>모든 태그는 닫는다.</p>

특히 내용이 없는 태그 사용에 주의한다.

<br/>
<input type="text" name="id"/>

이런 태그를 독립형 태그라고 한다.

<area>, <meta/>, <base/>, <col>, <frame>, <link/>, <br/>, <hr/>, <img/>, <input/>, <param/>

다음은 독립형 태그로 혼동하기 쉬운 컨테이너 태그이다.

<script></script>, <object></object>, <div></div>


style과 script 태그의 내용은 모두 주석 처리한다.  style 혹은 script 태그 안에서 XML 태그 요소를 사용하려면 항상 주석 처리한다.

<script><!--

  function doAction() {
    if (a < b) ...
  }

//--></script>


(2) 이미지 사용의 최소화

이미지 사용을 최소화하며 반복적인 이미지를 사용해야 하는 경우에 CSS의 background-image 속성으로 처리한다.

간격 조절을 위한 투명 이미지는 절대로 사용하지 않는다.

이미지의 크기는 이미지 파일의 절대 크기를 그대로 사용한다. 따라서 width와 height를 img 태그에 지정하지 않는다. 그러나 width와 height 속성을 명시적으로 지정하면 웹 브라우저 처리 속도의 향상을 기대할 수 있다.


(3) 구성 요소 간의 간격 조절

HTML 구성 요소 간의 간격 조절에 투명 이미지나 br 태그나 &nbsp;의 사용을 지양하고 CSS로 조정한다.


(4) 태그의 속성 값의 최소화

HTML로는 자료의 내용 및 구조만을 표현하며, UI 표현과 관련한 정보는 CSS로 나타낸다. 따라서 HTML 태그 속성 사용을 최소화한다.


(5) 들여 쓰기 규정

들여 쓰기는 탭이 아닌 스페이스 4자로 한다.


(6) table 태그의 사용

table 태그는 그리드 형 데이터 표현에만 사용한다. table 태그로 레이아웃을 표현하는 것은 지양해야 하며, table 태그 안에 table 태그가 들어가는 형식은 특별한 이유가 아니면 사용하지 않는다.

데이터를 위한 테이블의 경우, row와 column에 대한 헤더(th 태그)를 명기한다.


(7) 리스트 태그를 통한 구조적 데이터 표현

구조적인 데이터는 ul과 li 등의 리스트 태그로 표현한다.


(8) 상대 경로를 사용

모든 URL 경로의 표현은 상대 경로로 한다. 수정을 어렵게 하는 절대 경로를 사용하는 것은 지양한다.


(9) 텍스트를 이미지로 표현하는 것을 지양

텍스트를 이미지 파일로 표현하는 것을 지양한다. 이미지를 사용하면 네트워크 트래픽을 증가시키는 동시에 수정을 어렵게 한다.


(10) Content-based text styles

표현 방식을 지칭하는 b, big, i, small, sub, sup, tt 태그 사용을 지양하고(Physical Styles) 의미 방식을 지칭하는 strong, em 태그의 사용을 지향한다.

  • abbr - abbreviated form of a longer word or phrase
  • acronym - acronym
  • em - 강조해야 하는 내용
  • strong - 매우 강조해야 하는 내용
  • cite - 출처, 인용구
  • code - 프로그래밍 코드의 일부분
  • kbd - 사용자가 입력한 내용
  • samp - 샘플 내용
  • dfn - 정의
  • var - 변수


(11) 사용을 지양해야 하는 태그

center, font, basefont, u, s, strike, marquee 등의 태그 사용을 지양한다.


(12) 사용을 지양해야 하는 속성

태그의 align, style 등의 속성 사용을 지양한다.


(13) img 태그 사용의 지양

이미지를 표현하는데 있어서 img 태그의 사용은 지양하고 CSS의 background-image 속성의 사용을 지향한다.


(14) 개발 시 편집을 위한 태그의 활용

ins, del 등의 태그를 사용하여 개발 시 편집 정보를 기술한다.


4. CSS 작성 가이드라인

일반적인 CSS 작성 가이드라인은 아래와 같다.


(1) 소문자 사용

CSS의 내용은 모두 소문자로 작성한다.


(2) 들여 쓰기 규정

들여 쓰기는 탭이 아닌 스페이스 4자로 한다.


(3) 선택자

선택자는 태그의 이름, 태그의 클래스(class) 속성, 태그의 아이디(id) 속성 순으로 지정한다.
태그의 계층 구조를 사용하면 태그의 이름을 통한 선택자 사용 비율을 늘릴 수 있다.

table tbody tr td {
    background-color: #ffffff;
    font: 1em 굴림, Tahoma, sans-serif;
    height: 2em;
    padding: 0.5em 0.5em 0 1em;
    overflow: hidden;
}

클래스 속성이나 아이디 속성을 사용하는 경우에도 앞에 태그를 지정한다.

div.title-area {
    ...
}

div#header {
    ...
}


(4) 기본 설정의 초기화

html, body, form 태그 등의 기본 설정이 브라우저에 따라서 상이하다. 따라서 이를 CSS를 통해서 동일하게 설정한다.

html, body, form {
    margin: 0;
    padding: 0;
}


(5) 상속을 통한 속성 반복의 최소화

상속을 통하여 동일한 속성 값을 반복하는 것을 지양한다.

div {
    width: 775em;
}

div.title-area {
    color: #0b9af3;
    margin: 0 0 1em 0;
    padding-left: 2em;
}


(6) em을 이용한 크기 설정

해당 요소의 크기를 조정하기 위해 사용하는 여러 단위 중에서 em을 사용하여 크기를 조정한다. 단 border, margin, padding 등과 같은 경우에는 px를 사용할 수 있다.


(7) 색상 속성

색상(color) 속성에 대한 값은 색상 이름이 아닌, 헥사 코드로 표현한다.

bgcolor: #ffffff;

rgb로 표현할 수도 있다.

bgcolor: rgb(255, 255, 255);


(8) background-image 속성을 통해서 이미지 설정

background-image 속성을 통해서 HTML에서의 이미지(img) 태그 사용을 최소화한다.

div.title-area {
    background-image: url(../image/label/Title2.gif);
    background-position: 0 -2px;
    background-repeat: no-repeat;
    margin: 0 0 1em 0;
    padding-left: 2em;
}


(9) 집합 속성의 사용을 지향

CSS의 내용을 간결하게 가기 위해서 집합 속성을 사용한다. 아래는 개별 속성을 사용한 경우이다.

div.title-area {
    margin-top: 5px;
    margin-right: 4px;
    margin-bottom: 3px;
    margin-left: 2px;
}

위의 표현을 아래처럼 집합 속성으로 표현한다.

div.title-area {
    margin: 5px 4px 3px 2px;
}


(10) 웹 브라우저 독립적인 속성의 사용

특정 웹 브라우저에 종속적인 속성의 사용을 지양하며, W3C가 제공하는 아래의 속성 테이블을 중심으로 CSS 파일을 작성한다.

Cascading Style Sheets, level 2 CSS2 Specification, Appendix F. Property index (http://www.w3.org/TR/REC-CSS2/propidx.html)


(11) CSS 파일 수의 최소화

CSS 파일의 수를 최소화한다. 유사한 형태의 업무 화면은 하나의 CSS 파일로 조정한다. 각 업무 화면에 특징적인 요소를 별개의 CSS 파일로 지정하기 보다는 HTML의 style 태그를 이용해서 설정하는 것을 권장한다.

단 메인 화면, 사이트 맵 등 업무 화면과는 독립적인 화면에 대해서는 별도의 CSS 파일을 가져간다.


(12) 특기 사항

CSS와 관련한 특기 사항은 아래와 같다.

  • select 태그 CSS 적용 - border 속성을 지정할 수 없음


5. 참고 자료