파이어폭스 3.5 초기 부팅 과정이 느리다. 내 컴퓨터에서만 그런지는 모르겠지만 느리다.
느리다는 건 다른 웹 브라우저와 비교해도 파이어폭스 이전 버전하고 비교해도 그렇다.
프로그램 시작 자체도 느리지만, 즐겨 찾기 대신 Ctr + L 단축키로 URL을 직접 입력하는 내 사용 패턴이 더욱 답답하게 한다. 주소 입력 창에 URL을 입력할 때의 그 버벅임이란...
2009-09-06
마이크로소프트 익스프레션
오늘 오후에 종각 영풍 문고에서 시간을 보내다가 두꺼움에 혹해서 크리에이티브 웹이라는 잡지를 구매했다.
서점을 지나가면서 표지를 본적이야 있겠지만 실제 내용을 보기는 처음이었다. 우리나라에 이렇게 많은 웹 에이전시 회사가 있다는 사실을 알았다.
그러다가 뒷면 광고에 나온 마이크로소프트 REMOIX09 행사 내용에 포함되어 있는 마이크로소프트 익스프레션이라는 솔루션에 눈길이 갔다.
그 중에 SketchFlow가 있었는데 일종의 와이어프레임 솔루션인 것 같다.
서점을 지나가면서 표지를 본적이야 있겠지만 실제 내용을 보기는 처음이었다. 우리나라에 이렇게 많은 웹 에이전시 회사가 있다는 사실을 알았다.
그러다가 뒷면 광고에 나온 마이크로소프트 REMOIX09 행사 내용에 포함되어 있는 마이크로소프트 익스프레션이라는 솔루션에 눈길이 갔다.
그 중에 SketchFlow가 있었는데 일종의 와이어프레임 솔루션인 것 같다.
2009-09-02
홈페이지 메인 화면
http://www.gracesmith.co.uk

이런 디자인이 사람에게 주는 의미가 다양하겠지만 나는 좋다^^
http://vaadin.com

텍스트가 얼마나 중요한 요소인지를 보여준다.
이런 디자인이 사람에게 주는 의미가 다양하겠지만 나는 좋다^^
http://vaadin.com
텍스트가 얼마나 중요한 요소인지를 보여준다.
2009-09-01
와이어프레임
구글 리더로 구독하는 Smashing Magazine에서 와이어프레임(Wireframes)과 관련한 35 Excellent Wireframing Resources을 보았다.
처음 알았는데 화면 스케치를 와이어프레임이라고 하는 것 같다. 혹은 프로토타입이라고 하거나...
파워포인트나 모델링 도구와는 달리 스케치 느낌을 살린 화면 스케치를 프로그램으로 구현할 수 있을까 생각한 적이 있는데 이를 구현한 제품(iPlotz)도 볼 수 있었다.
종이로 그린 후에 디지털 카메라나 스케너로 스캔하는 것과 이런 애플리케이션을 사용하는 것 중에서 어느 것이 더 생산적일까?
요구사항 관리 애플리케이션이 텍스트 편집기와 와이어프레임 편집기를 함께 제공하면 좋을 듯 하다. 여기디가 유스케이스 모델링 정도까지 추가해서...
와이어프레임 도구
Balsamiq Mockups
관련 글
MockupScreens Review
처음 알았는데 화면 스케치를 와이어프레임이라고 하는 것 같다. 혹은 프로토타입이라고 하거나...
파워포인트나 모델링 도구와는 달리 스케치 느낌을 살린 화면 스케치를 프로그램으로 구현할 수 있을까 생각한 적이 있는데 이를 구현한 제품(iPlotz)도 볼 수 있었다.
종이로 그린 후에 디지털 카메라나 스케너로 스캔하는 것과 이런 애플리케이션을 사용하는 것 중에서 어느 것이 더 생산적일까?
요구사항 관리 애플리케이션이 텍스트 편집기와 와이어프레임 편집기를 함께 제공하면 좋을 듯 하다. 여기디가 유스케이스 모델링 정도까지 추가해서...
와이어프레임 도구
Balsamiq Mockups
인상적임
Mockup Screens관련 글
MockupScreens Review
2009-08-30
display: block과 inline
아래 태그는
웹 브라우저에 아래와 같이 표시된다.
반면에 아래 태그는
웹 브라우저에 아래와 같이 표시된다.

이 둘 사이에 나타나는 가장 큰 차이는 줄 바꿈 여부이다. div 태그는 줄바꿈되고, span 태그는 줄바꿈되지 않는다.
div 태그가 줄바꿈되는 이유는 CSS display 속성 기본 값이 block이기 때문이고, span 태그가 줄바꿈되지 않는 이유는 CSS display 속성 기본 값이 inline이기 때문이다.
아래처럼 반대로 설정하면
웹 브라우저에 아래와 같이 표시된다.

block과 inline의 차이점은 줄바꿈만은 아니다.
<div>div1</div>
<div>dIv2</div>
<div>div3</div>
<div>dIv2</div>
<div>div3</div>
웹 브라우저에 아래와 같이 표시된다.
<span>span1</span>
<span>span2</span>
<span>span3</span>
<span>span2</span>
<span>span3</span>
웹 브라우저에 아래와 같이 표시된다.
이 둘 사이에 나타나는 가장 큰 차이는 줄 바꿈 여부이다. div 태그는 줄바꿈되고, span 태그는 줄바꿈되지 않는다.
div 태그가 줄바꿈되는 이유는 CSS display 속성 기본 값이 block이기 때문이고, span 태그가 줄바꿈되지 않는 이유는 CSS display 속성 기본 값이 inline이기 때문이다.
아래처럼 반대로 설정하면
div {
display: inline;
}
span {
display: block;
}
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 태그를 드래그 앤 드랍하려면 우선 onmousedown 속성을 설정한다.
사용자가 div 태그를 마우스로 누른 순간에 onmousedown 속성으로 선언한 자바 스크립트 함수(drag - 아래에서 설명)가 수행된다.
drag 함수는 다음과 같다.
다음은 drag 함수 구현부이다. 우선 마우스 커서를 드래그를 의미하는 것으로 변경한다.
그리고 document에 대해서 onmousemove 이벤트 리스너를 설정한다.
마우스 커서 위치 값 추출에 Prototype 라이브러리를 사용했다. 자세한 사항은 다음을 참조한다.
그리고 document에 대해서 onmouseup 이벤트 리스너를 설정한다.
최종적인 drag 함수는 다음과 같다.
<div>드래그 앤 드랍</div>
위의 div 태그를 드래그 앤 드랍하려면 우선 onmousedown 속성을 설정한다.
<div onmousedown="drag(this, event);">드래그 앤 드랍</div>
사용자가 div 태그를 마우스로 누른 순간에 onmousedown 속성으로 선언한 자바 스크립트 함수(drag - 아래에서 설명)가 수행된다.
drag 함수는 다음과 같다.
/*
drag 함수의 첫번째 파라미터(element)는 드래그할 대상이고, 두번째 파라미터(event)는 이벤트이다.
*/
function drag(element, ev) {
}
drag 함수의 첫번째 파라미터(element)는 드래그할 대상이고, 두번째 파라미터(event)는 이벤트이다.
*/
function drag(element, ev) {
}
다음은 drag 함수 구현부이다. 우선 마우스 커서를 드래그를 의미하는 것으로 변경한다.
document.body.style.cursor = "move";
/*
마우스 커서는 드래그할 대상(<div>드래그 앤 드랍</div>)이 아닌 body에 설정해야 한다. 마우스를 드래그를 하면 마우스 포인터가 대상 밖으로 벗어나는 것이 일반적이기 때문이다.
*/
/*
마우스 커서는 드래그할 대상(<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;
};
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;
};
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;
}
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)을 모두 입력받는다.
사용자는 최소한의 정보만을 입력하면 된다.
- 아이디 대신 이메일 주소를 사용한다.
- 패스워드 뿐만 아니라 이메일 주소도 올바르게 입력했는지 확인한다.
- 시간대를 입력받는다.
Basecamp Signup 화면이다.
이름, 이메일, 아이디(Username)을 모두 입력받는다.
2009-08-25
탭 메뉴 작성
CSS와 ul/li 태그로 탭 메뉴를 작성하는 방법이다.
기본 설정
XHTML 1.0을 준수하여 ul, li 태그로 아래처럼 작성한다.
웹 브라우저에 아래처럼 표시된다.

탭 메뉴 1
CSS를 이용해서 ul, li 태그의 margin과 padding 값을 조정한다. 그리고 ul 태그의 list-style 속성 값을 none으로 한다.
웹 브라우저에 아래처럼 표시된다.

li 태그의 display 속성 값을 inline으로 한다.
웹 브라우저에 아래처럼 표시된다.

li 태그에 border 속성을 준다.
MS IE 6.0의 버그로 인해서 ul 태그 아래에 다른 태그가 없으면 선이 나타나지 않는다. 따라서 HTML을 아래처럼 수정한다.
모질라 파이어 폭스와 오페라에서는 아래 처럼 li 태그 사이에 간격이 생긴다.

이를 방지하기 위해서 아래처럼 li 태그 사이의 여백을 제거한다.

선택한 탭 메뉴는 클래스 속성으로 표현한다.
아래와 같은 CSS 스타일을 추가한다.
최종 결과는 아래와 같다.

탭 메뉴 2
배경 이미지를 이용해서 탭 메뉴를 수정한다.
앞의 예제에서 li 태그의 border 속성을 삭제하고 background 속성을 추가한다.

이미지를 이용했기 때문에 width 속성으로 넓이를 지정한다. 그리고 inline 요소는 넓이를 지정할 수 없기 때문에 display 속성을 삭제하고 float 속성의 값을 left로 지정한다. 그리고 좌우 padding 속성 값을 0으로 하고 텍스트를 가운데로 정렬한다.

기본 설정
XHTML 1.0을 준수하여 ul, li 태그로 아래처럼 작성한다.
<ul>
<li><span>소프트웨어</span></li>
<li><span>하드웨어</span></li>
<li><span>네트워크</span></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;
}
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;
}
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;
}
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><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>
<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>
<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;
}
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;
}
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;
}
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으로 설정한다.
예전에는 다음 방법을 사용한 적도 있는데 단점이 많았다.
이미지에 대한 외곽선 제거를 위한 설정
웹 브라우저마다 다른 기본 값 초기화
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;
}
/*
html과 form에 대해서도 초기화를 해준다.
모든 태그를 초기화하지는 않고 실제로 사용할 태그들에 대해서만 초기화한다.
*/
예전에는 다음 방법을 사용한 적도 있는데 단점이 많았다.
* {
border: 0;
margin: 0;
padding: 0;
}
border: 0;
margin: 0;
padding: 0;
}
이미지에 대한 외곽선 제거를 위한 설정
a img {
border: 0;
}
border: 0;
}
테이블 작성
CSS와 HTML에 관심을 갖게된 계기가 table 목록이었다. 2003년 가을에 참여했던 프로젝트에서 웹 디자이너가 작성한 table 목록은 다음과 같았다.
그러다가 CSS padding 속성으로 이를 손쉽게 제어할 수 있다는 걸 알게 되면서 CSS와 HTML에 대한 관심을 가지게 되었다.
그 이후로 이런 저런 시행착오를 거쳐 지금 주로 사용하는 table 태그로 목록을 작성하는 간결한 방법은 다음과 같다. 우선 table 태그를 다음과 같이 작성한다.
지금까지 작업 내용을 웹 브라우저로 보면 다음과 같다.
th와 td 태그에 선을 설정한다.
이러면 선은 표시되지만 셀과 셀 사이에 여백이 보인다.
이 셀과 셀 사이 여백은 다음과 같이 제거한다.
그리고 답답함을 없애기 위해서 셀에 여백을 준다.
문자열이 긴 경우에는 셀 안에서 줄 바꿈이 일어나기 때문에 line-height 보다는 padding 속성으로 상하 여백을 설정한다.
그리고 목록 이름에 대해서 배경색을 준다.
다음은 최종적인 모습이다.

table01.html
- table 태그 안에 table 태그를 넣고 첫번째 테이블 배경색으로 선을 표시한다.
- 선과 글자 사이의 간격은 로 하는 것이었는데, 결과적으로 를 제대로 신경쓰지 않는 게으름이나 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>
<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 {
border: 1px solid silver;
}
border: 1px solid silver;
}
이러면 선은 표시되지만 셀과 셀 사이에 여백이 보인다.
table {
border-collapse: collapse;
}
border-collapse: collapse;
}
그리고 답답함을 없애기 위해서 셀에 여백을 준다.
th, td {
border: 1px solid silver;
padding: 4px 5px;
}
border: 1px solid silver;
padding: 4px 5px;
}
문자열이 긴 경우에는 셀 안에서 줄 바꿈이 일어나기 때문에 line-height 보다는 padding 속성으로 상하 여백을 설정한다.
그리고 목록 이름에 대해서 배경색을 준다.
thead {
background: navy;
color: white; /* 배경색을 설정하면 글자 색도 함께 지정하는 것이 일반적이다. */
}
background: navy;
color: white; /* 배경색을 설정하면 글자 색도 함께 지정하는 것이 일반적이다. */
}
다음은 최종적인 모습이다.
다운로드 편의를 위해서 HTML에 CSS를 포함시켰다.
2009-07-17
자바 2D 두선이 교차하는 지점
http://blog.persistent.info/2004/03/java-lineline-intersections.html
http://mathworld.wolfram.com/Line-LineIntersection.html
http://mathworld.wolfram.com/Line-LineIntersection.html
2009-07-15
웹 브라우저 버전 체크
클라이언트나 서버 프로그래밍에서 사용자 웹 브라우저 정보를 알아야 하는 경우가 있다. 이를 위한 방법이다.
자바 스크립트에서는 아래 함수를 사용한다.
자바에서는 아래 메소드를 사용한다.
Ruby on Rails에서는 아래 함수를 사용한다.
자바 스크립트에서는 아래 함수를 사용한다.
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;
}
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;
}
}
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
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
2009-07-02
로그
Apache log4j와 Apache Commons Logging을 사용하는 것이 고전적인 방법이기는 하지만
사용하는 라이브러리를 줄이기 위해서 Java Logging API를 사용하는 것을 권장한다.
* 톰켓을 사용하는 경우에는 톰켓 기본 설정 사용
* 동적으로 로깅 관련 설정을 변경할 수 있는가?
사용하는 라이브러리를 줄이기 위해서 Java Logging API를 사용하는 것을 권장한다.
* 톰켓을 사용하는 경우에는 톰켓 기본 설정 사용
* 동적으로 로깅 관련 설정을 변경할 수 있는가?
2009-02-26
Ruby Gems 업데이트 오류
회사 홈페이지 개편 작업 때문에 노트북(윈도우즈 XP)에 루비를 설치했다.
그리고 Ruby on Rails 설치를 위해서 Ruby Gems를 최신으로 업데이트했다.
그런데 gem 명령어를 실행하면 정상적으로 동작하지 않았다. 다음 메시지가 출력되었다.
그래서 RUBY_HOME/bin/gem.bat 파일의 마지막 줄을
에서
으로 수정하였다.
ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]
그리고 Ruby on Rails 설치를 위해서 Ruby Gems를 최신으로 업데이트했다.
gem update --system
그런데 gem 명령어를 실행하면 정상적으로 동작하지 않았다. 다음 메시지가 출력되었다.
파일 이름, 디렉터리 이름 또는 볼륨 레이블 구문이 틀립니다.
그래서 RUBY_HOME/bin/gem.bat 파일의 마지막 줄을
@"ruby.exe"" "%~dpn0" %*
에서
@"ruby.exe" "%~dpn0" %*
으로 수정하였다.
2009-01-20
아파치 톰켓 6.0 한글 처리
아파치 톰켓 6.0에서 한글 처리 설정을 하는 방법은 다음과 같다. UTF-8을 사용하는 것으로 가정한다.
1. GET
${catalina.base}/conf/server.xml 파일에서 Connector 태그에 URIEncoding 속성을 설정한다.
${catalina.base}는 톰켓을 설치한 디렉토리를 의미한다.
2. POST
서블릿 필터를 이용해서 javax.servlet.ServletRequest 객체의 setCharacterEncoding 메소드를 호출한다.
* ServletRequest 객체의 getParameter 메소드를 호출하기 전에 setCharacterEncoding 메소드를 호출해야 한다.
3. Content Type
javax.servlet.ServletResponse 객체의 setContentType 메소드로 content-type을 지정한다.
JSP에서 page 선언부로 설정할 수도 있다.
JSP 컴파일과 관련된 pageEncoding 속성도 설정한다.
4. HTML
meta 태그는 title 태그 앞에 있어야 한다.
5. 참고 자료
1. GET
${catalina.base}/conf/server.xml 파일에서 Connector 태그에 URIEncoding 속성을 설정한다.
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8"/>
redirectPort="8443" URIEncoding="UTF-8"/>
${catalina.base}는 톰켓을 설치한 디렉토리를 의미한다.
2. POST
서블릿 필터를 이용해서 javax.servlet.ServletRequest 객체의 setCharacterEncoding 메소드를 호출한다.
request.setCharacterEncoding("UTF-8");
* ServletRequest 객체의 getParameter 메소드를 호출하기 전에 setCharacterEncoding 메소드를 호출해야 한다.
3. Content Type
javax.servlet.ServletResponse 객체의 setContentType 메소드로 content-type을 지정한다.
response.setContentType("text/html; charset=UTF-8");
JSP에서 page 선언부로 설정할 수도 있다.
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
JSP 컴파일과 관련된 pageEncoding 속성도 설정한다.
4. HTML
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
meta 태그는 title 태그 앞에 있어야 한다.
5. 참고 자료
- Character Conversions from Browser to Database
- Developing J2EE Global Applications : Character Encoding
2008-12-19
display: none과 visibility: hidden
CSS에서 display 속성을 none으로 설정하는 것과 visibility 속성을 hidden으로 설정하는 것은 비슷하지만 명확한 차이가 있다.
다음 HTML이 있다.
CSS 설정은 다음과 같다.
웹 브라우저에 아래와 같이 표시된다.

먼저 두번째 태그(two) display 속성을 none으로 설정하면
웹 브라우저에 아래와 같이 표시된다.

display 속성을 none으로 설정하면 해당 태그가 HTML 문서 상에 존재하지 않는 것과 같이 된다. 즉, 태그가 아래와 같다고 할 수 있다.
반면에 두번째 태그(two) visibility 속성을 hidden으로 설정하면
웹 브라우저에 아래와 같이 표시된다.

visibility 속성을 hidden으로 설정하면 해당 태그 내용은 보이지 않지만 해당 태그가 차지하는 공간은 비워진채로 표시된다.
다음 HTML이 있다.
<div id="one">One</div>
<div id="two">Two</div>
<div id="three">Three</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;
}
border: 1px solid silver;
height: 15px;
margin: 10px 0;
text-align: center;
width: 200px;
}
웹 브라우저에 아래와 같이 표시된다.
먼저 두번째 태그(two) display 속성을 none으로 설정하면
#two {
display: none;
}
display: none;
}
웹 브라우저에 아래와 같이 표시된다.
display 속성을 none으로 설정하면 해당 태그가 HTML 문서 상에 존재하지 않는 것과 같이 된다. 즉, 태그가 아래와 같다고 할 수 있다.
<div id="one">One</div>
<div id="three">Three</div>
<div id="three">Three</div>
반면에 두번째 태그(two) visibility 속성을 hidden으로 설정하면
#two {
visibility: hidden;
}
visibility: hidden;
}
웹 브라우저에 아래와 같이 표시된다.
visibility 속성을 hidden으로 설정하면 해당 태그 내용은 보이지 않지만 해당 태그가 차지하는 공간은 비워진채로 표시된다.
Subscribe to:
Posts (Atom)