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-27

간단한 사용자 가입 폼 - Mint/Basecamp

Mint Account Center 화면이다.



사용자는 최소한의 정보만을 입력하면 된다.

  • 아이디 대신 이메일 주소를 사용한다.
  • 패스워드 뿐만 아니라 이메일 주소도 올바르게 입력했는지 확인한다.
  • 시간대를 입력받는다.


Basecamp Signup 화면이다.



이름, 이메일, 아이디(Username)을 모두 입력받는다.

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를 포함시켰다.