IT_Programming/HTML&CSS

HTML5 & Responsive Web Design.

JJun ™ 2011. 5. 30. 16:00

-----------------------------------------------------------------------------------------------

출처: http://naradesign.net/wp/2011/05/27/1483/

-----------------------------------------------------------------------------------------------

 

 

최근 블로그를 HTML5와 반응형 웹 디자인으로 리팩토링 했습니다.

제목은 거창한데 사실 별것 없습니다. 바꾸는데 하루도 걸리지 않았고 무엇을 바꾸었는지

소스 코드를 한 줄씩 설명해 보겠습니다.

 

 

HTML5

HTML5로 변경하는데는 약 2~3시간 정도 밖에 걸리지 않았습니다. 하지만 고민했던 시간은 꽤 길었습니다. div, section, article 요소를 혼동하지 않기 위해서 의미를 정확하게 이해해야

했습니다. DTD를 변경하고 header, footer 같은 새 요소들을 사용하면 IE6와 같은 낡은

브라우저에서 저 낮선 요소들을 어떻게 처리하는지 걱정도 했습니다.

 

HTML5 DTD declaration

HTML5 DTD는 매우 간단합니다. 예전에는 DTD를 외워보려고 갖은 애를 써도 그러지 못했는데 이제는 잊으려 애를 써도 잊지를 못합니다. <!doctype html> 이라고 적으면 끝입니다. case-insensitive. 대소문자를 구별하지 않으니 대문자로 쓰거나 소문자로 쓰거나 섞어 쓰거나 상관 없습니다. HTML5는 DTD 뿐만 아니라 요소와 속성 모두 case-insensitive 입니다. 대소문자를 구별하지 않습니다. 그러나 요소 이름과 속성을 대문자로 쓴다고 하면 말리고 싶습니다. 다른 이유는 없구요. 보기 불편하니까요.

 

Human language declaration

WCAG 2.0 지침의 3.1.1 항목을 보면 다음과 같은 구문이 있습니다.

 

"페이지 언어: 모든 웹 페이지의 기본 휴먼 랭귀지는 기계적으로 판단할 수 있어야 한다. (수준 A)"

 

휴먼 랭귀지란 사람이 쓰는 자연어를 말합니다. 수준 A란 최소한의 요구 조건 입니다.

<html lang="ko">

 

이렇게 html 요소에 한국어 휴먼 랭귀지 선언을 할 수 있습니다. 웹 문서에 휴먼 랭귀지를

선언하면 텍스트를 음성으로 변환해주는 시각장애인용 화면낭독기는 적합한 음성 엔진을

이용해서 웹 문서를 읽어줍니다. 예를 들어 로마자는 영어에만 쓰이는 것이 아니라 유럽에서 두루 쓰이는데요. 휴먼 랭귀지 속성을 선언하면 시각장애인용 화면 낭독기가 로마자를 어떻게 발음을 해야 하는지 정확히 알 수 있습니다.

 

한국형 웹 콘텐츠 접근성 지침인 KWCAG 2.0 지침에도 동일한 내용이 포함되어 있습니다. KWCAG 2.0에 포함되어 있다는 것은 향후 웹 접근성 품질마크 심사 지표에도 반영이 된다는 의미 입니다. 다음 회차의 웹 접근성 품질마크에는 이 기준이 적용되므로 웹 접근성 품질마크 심사에 도전하는 제작자는 반드시 휴먼 랭귀지를 작성해야 합니다. 이것은 HTML5 뿐만

아니라 다른 버전의 마크업 언어(HTML, XHTML)에도 동일하게 적용됩니다.

 

HTML5 enabling script

HTML5에는 여러가지 새로운 요소들이 등장 했습니다. 그러나 낡은 브라우저들은 이것을

알아차리지 못하는 문제가 있기 때문에 새로운 HTML5 요소들을 해석하거나 렌더링하지

않습니다. 도통 사람들이 업데이트를 하려고 하지도 않고 자동으로 업그레이드를 해주지도

않는 IE 6~8 브라우저가 그렇습니다. 우리는 낡은 브라우저가 새 요소들을 인식할 수 있도록 스크립트로 처리할 수 있습니다. 이 스크립트는 문서 head에 포함해서 브라우저가 낮선 태그를 만나 허둥대는 일이 없도록 처리하는 것이 좋습니다.

더보기

Since HTML5 is getting more attention by way of marking up our new pages, and the only way to get IE to acknowledge the new elements, such as <article>, is to use the HTML5 shiv, I've quickly put together a mini script that enables all the new elements.

Usage & Download

The html5.js and must be inserted in the head element (this is because IE needs to know about the element before it comes to render them - so it can't sit in the footer of the page, i.e. below the elements in question).

I've now moved HTML5 shiv to be hosted on a Google code project with the correct mime type being served, so if you're happy with the extra HTTP request, you can hot link the script: http://html5shim.googlecode.com/svn/trunk/html5.js

It's conditional within the code, so Firefox et al won't run the code - but it doesn't hurt to wrap it in an IE conditional call to reduce the http pulls for other browsers:

<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

I've also minified the file, so it's a matter of bytes to download.

 

 

<!–[if lt IE 9]> 
    <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 
<![endif]–>

 

"if lt IE 9 = if less-than IE 9" IE 조건부 주석을 사용해서 IE9 보다 버전이 낮은

브라우저에서만 이 스크립트를 해석하도록 한 것입니다. 스크립트는 새로 나온 HTML5

요소들을 브라우저가 인식할 수 있도록 추가해서 낡은 브라우저들이 HTML5 요소들을

해석하고 렌더링 할 수 있도록 해줍니다.

 

CSS Reset

새로 추가된 요소들이 inline 요소인지 block 요소인지 브라우저들은 모를 수 있습니다.

따라서 다음과 같이 CSS display 상태를 정의해 줍니다. HTML5에서 새롭게 추가된 요소들을

모두 block으로 선언 했습니다.

 

header, footer, section, article, aside, nav, hgroup, details, menu, figure, figcaption { 
    display: block 
}

 

 

HTML5 Markup – Document Structure

의미론적 마크업을 글로만 배우면 막상 실무에 적용할 때 생각하지 못했던 고려사항들이

발생해서 고민도 되고 마크업을 하더라도 확신이 서지 않게 됩니다.

 

그런 의미에서 개인 블로그는 좋은 실험 재료인 것이죠. 제 블로그의 마크업 구조는

다음과 같습니다. 

  • div
    • header
      • h1
    • section
      • article
        • h1
      • section
        • h2
      • section
        • h2
        • form
      • nav
    • nav
      • ol
        • li
    • footer

조금 더 자세히 풀어 볼까요?

  • div – 본문의 폭을 제한하거나 중앙으로 배치하는 역할만 합니다. 별 의미는 없기에 div 요소를 사용 했습니다.
    • header – 사이트 제목과 설명이 등장하는 헤더 섹션입니다.
      • h1 – 사이트 최상위 제목.
    • section – 헤더, 풋터, 네비게이션 섹션이 아닌 일반적인 섹션입니다. section 요소는 웹 문서의 구조를 결정하는 핵심 요소 입니다. 섹션은 통상 하나의 헤딩과 명시적인 관계를 갖는것이 좋습니다. section & hx의 관계는 마치 fieldset & legend 요소와 구조적으로 흡사합니다. section 안에 포함된 hx는 section 내부에 포함된 콘텐츠의 제목이 됨과 동시에 현재 웹 문서의 개요 역할을 합니다. 제 블로그의 경우 section 요소와 hx 요소 사이에 article이 끼어들어 section이 제목 없이 글 본문, 댓글, 댓글 쓰기 폼을 감싸는 역할을 하고 있습니다. section은 바로 아래 첫 번째 자식으로 hx를 갖추는 것을 구조적으로 권장하지만 제 경우는 그러지 못했네요. 하지만 꼭 그런 구조를 갖추지 못해도 괜찮습니다. hx가 없어도 section은 section 이니까요.
      • article – 포스트 본문 섹션으로써 처음에는 section 요소와 어떤 의미적 차이를 지니는지 구분하기 어려웠습니다. 그러나 article 요소는 이 영역을 독립적으로 다른곳에 옮겨놔도 하나의 완전한 문서 또는 섹션이 될 수 있는 ‘재 사용’ 가능한 또는 ‘배포 가능한’ 본문 영역이라고 설명할 수 있겠습니다. section 요소와 마찬가지로 hx 요소를 갖는것을 강력하게 권장합니다. section과 article 요소 가운데 무엇을 써야 할지 망설여질 때에는 주변의 맥락과 분리하여 독립해도 하나의 완전한 콘텐츠가 되는지 아닌지를 판단해 보세요. 독립적이라면 article에 가깝고 현재 문서의 개요와 구조를 결정하는 역할이라면 section에 가깝습니다.
        • h1 – 포스트 본문 제목. h1이 두 번째 등장하죠. h1은 하나의 웹 페이지에 2번 이상 등장할 수 있습니다. W3C 웹 사이트도 이런 구조를 가지고 있으며 검색엔진 최적화에 좋습니다. 게시판에서 게시물 제목도 h1으로 마크업 하면 검색엔진으로부터 좋은 점수를 받을 수 있습니다. h1에 포함된 텍스트가 문서 헤드의 title 요소에도 들어가 있으면 금상 첨화죠. 제 블로그는 그렇게 처리되어 있습니다. 검색엔진이 좋아합니다.
      • section – 댓글 목록 섹션.
        • h2 – 댓글 목록 제목.
      • section – 댓글 쓰기 섹션.
        • h2 – 댓글 쓰기 제목.
        • form – 댓글 쓰기 폼.
      • nav – 이전 포스트 / 다음 포스트 네비게이션.
    • nav – 사이트 글로벌 네비게이션.
      • ol – 비순차 목록 컨테이너.
        • li – 네비게이션 항목.
    • footer – 저작물 이용 안내 및 RSS 주소를 담은 풋터 섹션.

 

 

HTML5 Markup – Form Controls

HTML5 Form의 위력은 아이폰을 사용하는 분들이면 쉽게 체감할 수 있습니다.

제 블로그에서는 다음과 같은 타입의 Form Control을 사용 했습니다.

 

제 블로그의 End-user 페이지에서 Form Control 이라고 해 봐야 검색창과 글쓰기창 뿐인데요.

적용 결과는 다음과 같습니다.

 

<input type="search" autocomplete=on" /> 
검색창의 인풋 타입이 search 입니다.

<input type="url" autocomplete=on"  /> 
댓글 쓰기 창에서 웹 사이트 주소 입력 인풋 타입이 url 입니다.

 

이 밖에도 HTML5에는 새롭게 추가된 다양한 input type이 있습니다.

아래 항목들은 HTML5에 새롭게 추가된 input type 입니다. 링크를 클릭하면 실제로 코딩된

페이지를 만날 수 있습니다. 현재는 오페라 브라우저만 input type을 거의 완벽하게 지원하고

있습니다. 오페라 브라우저를 통해 예제를 확인해 보세요. 다른 브라우저와는 다르게 인풋을

좀 더 편리하게 작성할 수 있도록 도울 것입니다.

HTML5의 인풋 타입을 적절하게 사용하면 아이폰 사용자에게 다음과 같이 문맥에 알맞는 자판을 보여줄 수 있습니다. 입력 커서가 인풋에 들어갔을 때 인풋 타입을 인식해서 최적화된 자판 배열을 표시합니다.

 

input type="search" 일 때 아이폰은 자판에 Search 키를 보여줍니다. 

아이폰으로 input type="search" 테스트 해보기.

 

input type="tel" 일 때 아이폰은 자판에 숫자와 + * # 키를 보여줍니다. 

아이폰으로 input type="tel" 테스트 해보기.

 

input type="url" 일 때 아이폰은 자판에 .com과 Go 키를 보여줍니다. 

아이폰으로 input type="url" 테스트 해보기. 

 

input type="email" 일 때 아이폰은 자판에 @와 . 키를 보여줍니다. 

아이폰으로 input type="email" 테스트 해보기.

 

input type="number" 일 때 아이폰은 자판에 숫자와 특수문자 키를 보여줍니다. 

아이폰으로 input type="number" 테스트 해보기.

 

 

 

Responsive Web Design

사용자가 어떤 해상도의 단말을 사용하든 그에 알맞는 뷰를 보여줄 수 있는 유연한 레이아웃 설계 기법입니다. 이름은 정말 근사하지만 막상 내용 뜯어보면 참 볼것 없습니다.

 

Mobile Viewport Declaration

모바일 단말기는 기본적으로 PC용 화면 전체를 작은 화면 안에서 모두 보여줍니다.

작은 화면에 전체를 담으려니 다음과 같이 글씨가 깨알만해져서 확대하지 않고는

보기가 어렵겠지요. (물론 아이폰4는 그냥 봐도 보입니다. 326dpi & 640*960px을

자랑하는 레티나 디스플레이잖아요.)

 

적당히 확대한 다음 수직 수평 스크롤을 해 가면서 어렵게 읽을 수 밖에 없습니다.

 

 

모바일 뷰포트를 선언하면 모바일 단말에 탑재된 웹 브라우저(Safari Mobile for the iPhone, Android browser, webOS browser in Palm Pre and Pixi devices, Opera Mini, Opera Mobile and BlackBerry browsers)는 웹 페이지를 적절히 크게 확대해서 보여줍니다.

 

<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=yes, target-densitydpi=medium-dpi" />
meta 태그의 각 속성에 대한 자세한 설명

 

그러나 콘텐츠의 너비가 크기 때문에 당연히 수평 스크롤이 필요합니다. 아래 이미지를

보면 아시겠지만 오른쪽에 내용이 더 있는데 잘려서 보이지 않습니다. 사용자는 여전히

수직 수평 스크롤을 모두 해야만 하는데 이것은 여간 짜증스러운 일이 아닙니다.

 

 

 

그래서 필요한 것이 바로 Responsive Web Design 입니다. 사용자가 어떤 해상도의 단말기를 가지고 있더라도 알아서 유연하게 콘텐츠를 정돈해서 보여주는 기술이 필요합니다.

 

한때는 320px의 화면 너비가 모바일 화면 크기의 대세가 될 줄 알았지만 지금은 그렇지 않습니다. 매우 다양한 해상도를 지닌 디바이스들이 쏟아져 나오고 있지요. 그렇게 새로운 단말기가 등장할 때마다 그 해상도에 맞는 웹 페이지 화면을 추가로 개발하시겠습니까?

세상에 그런 삽질을.

 

 

CSS3 Media Queries

CSS3에는 Media Query 라는 명세가 있고 최신 브라우저들(IE9, Chrome, Safari, Firefox, Opera)과 아이폰용 모바일 사파리 브라우저도 이를 지원하고 있습니다. 다음은 모바일 뷰포트를 설정해서 적당히 확대한 다음 Media Query를 이용해서 레이아웃을 알맞게 정돈한 제 블로그의 모바일 화면 입니다. 아름답지요.

 

 

 

미디어 쿼리 문법을 간단하게 살펴보죠. 제 블로그는 모바일 환경이든 아니든 불문하고

브라우저의 너비가 980px 이하로 작아지면 화면 우측에 있는 글로벌 네비게이션이

화면 아래쪽으로 뚝 떨어집니다. 지금 브라우저의 폭을 조절해서 한번 확인해 보세요.

 

IE 6~8 브라우저는 미디어 쿼리를 지원하지 않기 때문에 재현이 되지 않습니다.

(그 낡아 빠진 브라우저 좀 그만 쓰면 안될까요?)

 

@media all and (max-width:980px) {    /* 화면 너비가 980px 이하일 때에만 아래 코드를 실행 */
    .content{ float:none; width:auto }    /* 콘텐츠 플롯을 해제하고 너비를 자동으로 */
    .nav{ float:none; width:auto }    /* 네비게이션 플롯을 해제하고 너비를 자동으로 */
}

딱 이정도의 사용법만 알아도 반응형 웹 디자인은 게임 끝입니다. 

CSS3의 Media Query에 대해 더 자세히 알고 싶다면 아래 링크된 문서들을 참고해 보세요.