CSS frameworks 중 하나로 많은 사람들로부터 주목받고 있는 blueprintcss에는 기초 작업으로 다양한 종류의 웹 브라우저들이 기본적으로 가지고 있는 저마다 다른 스타일을 기본값으로 초기화 하는 reset.css 정의 파일을 가지고 있다. 이 파일은 Eric Meyer씨가 제안했던 reset 스타일을 기반으로 하고 있는데, 이 곳에는 body의 line-height 값으로 단위가 생략된 1.5가 지정되어 있다.

단위가 생략된 line-height을 사용하면 객체에 지정되어 있는 글꼴의 원래 크기에 단위가 생략된 line-height 수치를 곱한 결과 값을 돌려주게 되는데, 이렇게 하면 글꼴 크기가 서로 다를 경우, line-height도 글꼴 크기와 비례한 값을 얻을 수 있게 된다.

그런데, 최근 A List Apart에 올라온 “How to Size Text in CSS” 제목의 글을 읽고 나서, 단위가 생략된 line-height을 쓸 경우, 서로 글꼴 크기가 다른 여러 column들을 보유한 layout을 디자인 할 경우 vertical rhythm과 관련해서 문제를 안고 있는 것을 알 수가 있다. vertical rhythm을 추구하는 디자인은 글꼴 크기에 관계없이 일정한 line-height을 갖게 하려는 것이기에 당연한 얘기일 것이다. 그래서, vertical rhythem을 고려한 디자인이라면, line-height 값으로 글꼴 크기 변화에도 자유로운 상대적 단위인 em을 써주면 예제 페이지에서 보여주는 바와 같이 모든 브라우저들에서 글꼴 크기에 상광없이 일정한 line-height 값을 얻을 수 있단다.

결국, 다양한 구조의 column layout 디자인을 쉽게 해주는 것이 blueprintcss framework의 사용 목적이라면, line-height 값도 상황에 따라 단위를 써주는 것이 좋을 듯하다.

웹 개발 과정에 있어서 웹 페이지 속 UI 동작을 구현하는데 필요한 기본적인 기능들을 모아놓은 JavaScript Library들이 제공되면서 개발자들의 손을 한 시름 덜어주게 되었고, 결국 남은 여력을 프로젝트에 더 집중하게 되면서 작업의 효율성을 증가시켜 주었듯이, 마찬가지로 웹 페이지의 기본 layout을 잡을 때 반복적으로 수행되던 CSS 작업에서도 빠른 작업 수행 속도를 붙여줄 수 있는 framework 형태의 여러 조력자들이 등장하고 있다.

개인적으로 JavaScript Library로는 jQuery를 그리고 CSS framework로는 blueprintcss를 주로 사용하게 되면서, 예전에 공개했던 HTML 문서 생성을 위한 TextMate용 snippet에도 작은 변화가 있었다.
여기에 그 바뀐 내용을 공개하면, 우선 아래는 HTML 4.01 Strict DocType을 위해 “page4” tab trigger로 지정된 HTML snippet이다.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ko" dir="ltr">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>${1:Title}</title>
    ${2:<link rel="stylesheet" href="${3:css/blueprint/}screen.css" type="text/css" media="screen, projection" />
    <link rel="stylesheet" href="$3print.css" type="text/css" media="print" />
    <!--[lt IE 7]><link rel="stylesheet" href="$3lib/ie.css" type="text/css" media="screen, projection"><![endif]-->
    }<style type="text/css" media="screen">
    /* <![CDATA[ */
 
    /* ]]> */
    </style> 
    ${4:<script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
    }<script type="text/javascript">
    // <![CDATA[ 
        $0
    // ]]> 
    </script> 
  </head>
  <body id="${5:page}">
    <div class="container">
      <div class="column span-${6:24}">
        <h1>${7:Header}</h1>
      </div>
      <div class="column span-${8:20}">
        ${9:Main content}
      </div>
      <div class="column span-${10:4} last">
        ${11:Right sidebar}
      </div>
      ${12:<div class="column span-24">
        ${13:Footer}
      </div>}
    </div>
  </body>
</html>

기본적으로 지정되어 있는 HTML 문서의 구조는, 오른쪽에 작은 sidebar가 위치한 보편적인 2 column 구조로 위 아래에 Header와 Footer가 위치하고 있다.

다음은 같은 구조를 가진 XHTML 1.0 Strict DocType 문서를 위한 HTML snippet. tab trigger로 “page”가 지정되어 있다.

<!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" ${1:${2:xml:lang="ko"}${3: lang="ko"}} dir="ltr">
  <head>
    <meta http-equiv="Content-Type" content="${4:application/xhtml+xml}; charset=utf-8" />
    <title>${5:Title}</title>
    ${6:<link rel="stylesheet" href="${7:css/blueprint/}screen.css" type="text/css" media="screen, projection" />
    <link rel="stylesheet" href="$7print.css" type="text/css" media="print" />
    <!--[lt IE 7]><link rel="stylesheet" href="$7lib/ie.css" type="text/css" media="screen, projection"><![endif]-->
    }<style type="text/css" media="screen">
    /* <![CDATA[ */
 
    /* ]]> */
    </style> 
    ${8:<script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
    }<script type="text/javascript">
    // <![CDATA[ 
      $0
    // ]]> 
    </script> 
  </head>
  <body id="${9:page}">
   <div class="container">
      <div class="column span-${10:24}">
        <h1>${11:Header}</h1>
      </div>
      <div class="column span-${12:20}">
        ${13:Main content}
      </div>
      <div class="column span-${14:4} last">
        ${15:Right sidebar}
      </div>
      ${16:<div class="column span-24">
        ${17:Footer}
      </div>}
    </div>
  </body>
</html>

간단한 것이지만, 손놀림을 덜 수 있는 또 하나의 꼼수다.

현재 Ruby 홈 페이지에서 제공하고 있는 Ruby의 최신 Stable Version은 Ruby 1.8.6-p110 (실제 가장 최근의 patch 버전은 p111)이다. 이 놈은 Leopard에 기본 설치되어 있는 놈 보다도 더 많은 패치가 이루어져서 설치를 위해 터미널에서 일반적인 configure 명령을 입력하면 다음과 같은 오류가 뜨고 만다.

$ ./configure --prefix=/usr/local --enable-pthread --with-readline-dir=/usr/local --enable-shared --enable-install-doc
checking build system type... i686-apple-darwin9.0.0
.
.
.
ar rcu libruby-static.a array.o bignum.o class.o compar.o dir.o dln.o enum.o error.o eval.o file.o gc.o hash.o inits.o io.o marshal.o math.o numeric.o object.o pack.o parse.o process.o prec.o random.o range.o re.o regex.o ruby.o signal.o sprintf.o st.o string.o struct.o time.o util.o variable.o version.o  dmyext.o
gcc -g -O2  -fno-common -pipe -fno-common  -DRUBY_EXPORT  -I. -I.  -c main.c
gcc -g -O2  -fno-common -pipe -fno-common  -DRUBY_EXPORT  -I. -I.  -c dmydln.c
gcc -g -O2  -fno-common -pipe -fno-common  -DRUBY_EXPORT  -L.    main.o dmydln.o libruby-static.a -lpthread -ldl -lobjc   -o miniruby
./mkconfig.rb:191: [BUG] Segmentation fault
ruby 1.8.6 (2007-09-23) [i686-darwin9.0.0]
 
make: *** [.rbconfig.time] Abort trap

결국, 문제의 원인을 알아보기 위해 Google에게 물어 본 결과 다음과 같은 해결책을 담아놓은 글타래를 찾아냈다.
ruby-1.8.6-p111 build on osx 10.5.0 fails; ok on 10.4.10. bug or config? – Ruby Forum

해결 방법은 먼저, 터미널에서 내려받은 최신 Ruby 소스 디렉토리로 이동후, 위 글타래에서 제공하고 있는 ignore-gsetcontext.diff이름의 패치 파일을 내려받아 다음과 같이 적용해준다.

$ patch < ignore-gsetcontext.diff

그리고 나서 다시 컴파일 해주면 정상적으로 설치되면서 다음과 같은 최신 버전을 확인할 수 있다.

$ ruby --version
ruby 1.8.6 (2007-09-24 patchlevel 111) [i686-darwin9.0.0]

Leopard에서 최신 Ruby 버전을 설치할 때 문제를 일으켰던 원인은, 위 글타래의 말을 빌리자면, setcontext/getcontext 함수가 Leopard에 와서는 일반 UNIX 형식을 따르기 위해 수정되면서 생긴 문제라고 한다. 문제 해결을 위한 패치가 벌써 몇 주전에 ruby-core 팀에게 전달되었으나 아직 안 고쳐진 모양이다.

Opera 소속의 Rijk van Geijtenbeek씨가 필요할 때마다 웹 브라우저 안에서 잽싸게 참고할 수 있는 CSS 3 Quick Reference Panel을 공개하였다. 최근 여러 브라우저들이 실험적으로 새로운 CSS 3 속성들을 지원하기 시작하면서 앞으로 많은 참고가 될 듯 한데, Opera나 Firefox에서는 “Panel”(F4 – Opera) 혹은 “Sidebar”(F9 – Mozilla)에서 쉽게 꺼내볼 수 있는 형태로 추가할 수도 있으며 그냥 책갈피에 추가해 놓아도 큰 도움이 될 듯 하다.
이 밖에도 Rijk씨가 직접 내용을 갱신하면서 관리하고 있는 panel들의 모음 페이지에 가면, 웹 기술 전반에 걸친 다양한 Quick Reference들이 모여있는데, 마치 알짜 금광을 발견한 듯 눈이 번쩍 뜨인다. 이 곳에는 자신의 컴퓨터에 직접 저장해서 불러올 수 있게 panel들의 모음 zip 파일도 제공하고 있다.

날로 쓰는 사람은 그냥 감사할 따름. 😉

웹 페이지의 첫 로딩 속도를 줄여주는 여러 방법 중, 서버로의 요청 횟수를 최소화 하는 것은 웹 애플리케이션의 최적화 요소 중에서도 중요한 덕목이자 실제 적용하기에도 아주 손쉬운 방법이다.
보통 웹 페이지에서 치장을 목적으로 사용되는 백그라운드 이미지들은 많이 사용될수록, 자동으로 그 요청 횟수도 늘어나기 마련인데, 이를 줄이고자 하는 목적으로 쓰이는 기법으로 CSS Sprites 기법이 있다.

간단하게, 아이콘이나 버튼과 같은 반복돼서 표시되지 않는 그림들처럼 독립된 여러 그림을 하나의 그림으로 합쳐놓고 CSS의 background-position을 보일 요소에 따라 바꾸어서 표시하는 기법인데, 이렇게 하면 서버로의 요청 횟수를 줄여주면서 사이트 로딩 속도를 줄여주고 더불어서 내려받는 이미지의 크기까지 줄여줄 수 있는 부수적 효과를 얻을 수 있다.

표딱지의 배경 그림으로 사용된 CSS Sprites 이미지 이곳의 블로그에서도 오른쪽 옆구리 아래에 붙어있는 표딱지 그림들의 경우, 개별 이미지를 사용해서 웹 페이지에 표시하려면 모두 10번의 서버 요청이 필요한데, CSS Sprites 기법을 써서 왼쪽에 보이는 바와 같은 하나의 그림으로 모든 단추의 배경 그림들을 표시할 수 있었다.

실제 구현 방법은 아주 간단해서, unordered li들로 구성된 메뉴들의 각 li에 특정 id 값을 지정해 주고 a 태그 속에 있는 text node를 <span> 태그로 감싸고 난 후, 여기에 background image의 좌표값을 표시될 해당 위치에 맞게 지정해 주면 모든 작업이 끝난다.
한 가지 주의가 필요했던 것은 text 때문에 배경 그림이 일부 가려지는 것을 막기 위해, <span>에 적용한 CSS의 padding-left 값을 li의 너비만큼 주어서, 결과적으로 글자를 화면 바깥으로 밀어내어 표시되지 못하도록 하였다. 이렇게 해서, 마지막 CSS 적용 결과는 다음과 같다.

/* sidebar badges */
div#sidebar div#badges ul li {
  list-style-type: none;
  list-style-image: none;
  background-image: none;
  width: 80px;
  height: 15px;
  margin-bottom: 4px;
  overflow: hidden;
}
 
div#badges span {
  display: block;
  background-image: url(images/buttons-bg.png);
  background-repeat: no-repeat;
  padding-left: 80px;
  cursor: pointer;
}
 
div#badges #atom span {background-position: 0 0;}
div#badges #vxhtml span {background-position: 0 -15px;}
div#badges #vcss span {background-position: 0 -30px;}
div#badges #wcag span {background-position: 0 -45px;}
div#badges #uni span {background-position: 0 -60px;}
div#badges #cc span {background-position: 0 -75px;}
div#badges #mac span {background-position: 0 -90px;}
div#badges #safari span {background-position: 0 -105px;}
div#badges #firefox span {background-position: 0 -120px;}
div#badges #ichat span {background-position: 0 -135px;}

결과적으로, 서버 요청 횟수를 10번에서 하나로 줄였을 뿐만 아니라, 이미지의 전체 크기도 거의 1/5이나 줄어든 일거양득의 효과를 보여준다. 🙂

이렇게 눈에 띄는 장점이 있기 때문에, 여러 웹 페이지에서는 CSS Sprites 기법을 많이 사용하고 있는데, 일일이 그래픽 프로그램에서 여러 개의 그림을 하나의 이미지로 합치고 CSS 적용을 위한 그림의 좌표값을 얻기란 번거로울 수가 있다. 그래서, 이런 작업을 자동화해주는 도구들이 개발돼서 한둘씩 생겨나고 있는데, 대표적으로 Website Performance | CSS Sprite Generator가 있다. 이곳에서는 이미지들을 하나로 묶은 압축 파일(zip)을 올려놓으면 약간의 설정만으로 Sprite 이미지와 함께 CSS 적용 rule까지 한꺼번에 얻을 수 있어서 편하다.

아무쪼록, 이러한 기법이 널리 알려지고 많이 쓰였으면 한다.