본문으로 바로가기

기존에는 브라우저의 호환성을 유지하기 위해 browser sniffing 기법(자바스크립트의 navigator.userAgent 프로퍼티를 이용하는 방식)을 사용했습니다. 그러나 다양한 디바이스가 등장하고 HTML5와 CSS3가 웹표준으로 자리매김을 하고 있는 상황에서 브라우저마다 HTML5와 CSS3의 구현정도가 달라 기존의 browser sniffing 방식으로는 이러한 브라우저간의 호환성을 유지한다는 것은 불가능하게 되어 대체방안으로 Modernizr를 많이 사용하고 있습니다.

Modernizr 소개

Modernizr는 오픈소스 자바스크립트 라이브러리로, HTML5와 CSS3의 명세에 정의된 요소와 속성들에 대한 지원여부를 점검하는 방식으로 기존의 방식보다 더 정확한 분류가 가능하다.

  • 40개 이상의 신규 요소와 속성들을 테스트할 수 있다. 웹문서에 Modernizr 스크립트를 포함하면, 현재 브라우저가 CSS3(@font-face, border-radius, border-image, box-shadow, rgba() 등) 뿐만 아니라 HTML5의 기능(audio, video, localStorage, 새로 추가된 input 엘리먼트의 types과 attributes)에 대해서도 지원하는 정도를 점검할 수 있다.
  • Modernizr라는 자바스크립트 객체를 생성하여 boolean(true,false) 속성으로 지원여부를 판단하게 된다.
  • <html> 요소에 어떤 요소와 속성들이 지원되고 지원되지 않는지 클래스 값을 이용해 표현해 준다.
  • 제공하는 script loader를 사용하여 구형 브라우저에 polyfill를 제공할 수 있다. 자바스크립트를 이용하여 지원 안되는 부분에 대한 기능을 추가할지 아니면 단순히 웹페이지의 기능을 축소할지에 대한 결정도 할 수 있게 된다. 특히 구형 IE에서 지원하지 않는 HTML5의 header, nav, main, section, aside, footer를 지원하기 위해 html5 Shiv를 추가할 수 있다.

Modernizr 2.7.0 에서는 html5 Shiv에 <main> 요소가 추가되었다.

Modernizr는 점진적인 기능개선 원칙하에 개발되었기 때문에, 웹사이트를 자바스크립트를 전혀 사용하지 않는 경우에서부터 기능개선을 위해서 단계별로 레이어를 추가할 수 있도록 지원한다. 오히려 이러한 단계별 개발방식을 권장하고 있다.

브라우저 지원

  • IE6+, Firefox 3.5+, Opera 9.6+, Safari 2+, Chrome
  • mobile, iOS's mobile Safari, Android's WebKit browser, Opera Mobile, Firefox Mobile and whilst we’re still doing more testing we believe we support Blackberry 6+.

Modernizr 사용법

Modernizr 홈페이지에 접속하면 Development 버전과 Production 버전을 다운로드 할 수 있다.

  • Development : 개발 버전이기 때문에 Non-core detects와 Media Queries를 제외한 모든 것을 포함하고 있다. 압축되지 않아 Modernizr 코드를 살펴 볼 수 있다. 테스트 용도에서 많이 사용한다.
  • Production : 실제 서비스 단계에서 사용하는 것으로 지원 여부를 확인해야 하는 항목들만 선택할 수 있다. 압축되어 있다.

Modernizr builder 소개

현재 버전업이 되어 Modernizr 3.0이 베타 테스트 중이다. 아래는 2.x 버전대의 설명이나 크게 다름은 없다.

HTML과 CSS 섹션은 각각의 요소와 속성의 지원여부를 테스트할 것을 지정할 수 있다. HTML5 섹션은 이미 html5shiv를 포함할 경우 이미 활성화되었기 때문에 실제로는 HTML5 태그를 포함하고 있지는 않다. 대신에 HTML5의 기능확장을 위한 엘리먼트을 포함하고 있다.

Misc 섹션은 특정 브라우져에서 좀 더 복잡한 항목들을 사용할 수 있게 해 준다. 사실 box-sizing: border-box를 사용하고자 한다면 polyfill 기능을 해제할 경우도 있다.

Modernizr의 Extra 섹션은 html5shiv, yepnode.js, respond.js(media queries) 와 CSS class를 추가하기가 있다.

modernizr extra

html5shiv

IE 6~9, 사파리 4.x(아이폰 3.x 폼함), 파이어폭스 3.x 브라우저에서 HTML5의 디폴트 스타일을 적용할 수 있게 해주고 특히 레거시 IE에서 HTML5의 section 요소들을 사용할 수 있게 해 주는 툴이다.

html5shiv w/ printshiv

프린트를 해야할 필요가 있을 때 이 옵션을 선택해야 한다.

Modernizr.load

Monernizr.load는 pollyfill을 이용한다면 대역폭과 성능을 향상시키는데 도움이 된다. yepnope.js를 추가하는데 이는 이름에서 알 수 있듯이 호환성여부를 yes(yep) or no(nope) 로 알수 있도록 해 준다. 임의 조건에 따라 해당하는 스타일 클래스를 적용해 주는 작은 크기(3k)의 자바스크립트이다. 조건에 맞는 특정 파일을 서브할 수 있게 해준다. 이 로더는 Modernizr.load() 함수를 사용할 수 있게 해 준다.

Media Queries

respond.js를 인클루드하며 CSS3 Medial Queries 기능을 사용할 수 있다. 이것은 Modernizr 없이도 사용할 수 있다.

Add CSS Classes

<html> 요소에 클래스를 추가해서 지원하는 CSS3 속성들을 알수 있게 한다.

Modernizr 삽입

<head> 요소에 다운로드한 스크립트를 삽입한다.

<head>
  <link rel="stylesheet" href="css/main.css" />
  <script src="js/vendor/modernizr-2.6.2.min.js"></script>
</head>     

성능적인 측면에서 스타일시트 다음에 위치하는 것이 추천된다.

  • html5 Shiv는 <body> 요소 이전에 실행되어야 하기 때문이다.
  • Modernizr를 이용해 CSS 클래스들을 추가한다면 FOUC를 예방하기 위해 필요하다.

FOUC는 외부의 CSS가 불러오기 전에 잠시 스타일이 적용되지 않은 웹 페이지가 나타나는 현상이다. 이 현상은 스타일이 적용되지 않은 웹 페이지가 스타일이 적용된 웹 페이지로 변화하는 것이다. 브라우저가 웹 페이지에 스타일 정의를 부르고 적용할 때 보여지는 부분을 최대한 빨리 수정하지만, 이 변화는 짧지 않은 시간 동안 나타나므로 사용자는 페이지에 오류가 있다는 생각을 하게된다. FOUC는 CSS와 HTML의 버전 변화와는 관계가 없으며, 이것은 브라우저의 문제로 보인다. ...

만일 IE8 이하 버전을 지원하지 않기를 원하거나 FOUC를 개의치 않는다면 원하는 곳에 추가해도 된다.

no-js 추가

<html> 요소에 class="no-js"를 추가한다.

<html class="no-js">

Modernizr가 실행되면서 자바스크립트가 사용가능하다면 no-js 부분은 js로 변경되고 위에서 설명한 Modernizr builder에서 체크한 속성들을 검사하여 지원하지 않는 속성에 대해서는 해당 클래스명 앞에 no-를 삽입해주게 된다.

이후 지원되지 않는 속성들에 대한 대체 CSS를 추가하면 되는데 자세한 설명은 이 페이지의 하단에 작성하기로 한다.

Modernizr.load() 사용법

Modernizr.load is a resource loader (CSS and JavaScript) that was made to specifically to work side-by-side with Modernizr. Monernizr.load는 pollyfill을 이용한다면 대역폭과 성능을 향상시키는데 도움이 된다.

Modernizr.load({
  test: Modernizr.geolocation,
  yep : 'geo.js',
  nope: 'geo-polyfill.js'
});

위의 예제처럼 브라우저에서 geolocation의 지원 여부에 따라 서로 다른 스크립트를 로드할 수 있다. 이와 같은 방법으로 불필요한 코드를 다운로드 하는 것을 막을 수 있어 대역폭을 감소시키고 페이지 성능을 향상시킨다.

Modernizr.load는 작고 간단하지만, 어렵고 복잡한 일을 잘 처리한다. 아래는 한 꺼번에 여러개의 기능 검사와 pollyfill 적용방법이다.

// Give Modernizr.load a string, an object, or an array of strings and objects
Modernizr.load([
  // Presentational polyfills
  {
    // Logical list of things we would normally need
    test : Modernizr.fontface && Modernizr.canvas && Modernizr.cssgradients,
    // Modernizr.load loads css and javascript by default
    nope : ['presentational-polyfill.js', 'presentational.css']
  },
  // Functional polyfills
  {
    // This just has to be truthy
    test : Modernizr.websockets && window.JSON,
    // socket-io.js and json2.js
    nope : 'functional-polyfills.js',
    // You can also give arrays of resources to load.
    both : [ 'app.js', 'extra.js' ],
    complete : function () {
      // Run this after everything in this group has downloaded
      // and executed, as well everything in all previous groups
      myApp.init();
    }
  },
  // Run your analytics after you've already kicked off all the rest
  // of your app.
  'post-analytics.js'
]);

Modernizr.load의 특징중에 하나가 스크립트의 실행과 로드가 분리되어 있다는 것이다. HTML5 Boilerplate처럼 Google CDN을 이용하는 jQuery fallback과 같다.

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"></script>
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.7.1.min.js">\x3C/script>')</script>

스크립트를 로드를 시도했을 때, 바로 이후 jQuery 객체를 이용가능한지 테스트한다. 만일 이용 불가능하다면 jQuery fallback으 로컬에서 사용할 수 있게 된다. 이 방법은 직렬이 아닌 병렬( in serial instead of in parallel)로 강제적으로 스크립트를 로드하기 때문에 성능이 저하될 수 있으니 fallback으로만 사용하도록 하자.

Modernizr.load([
  {
    load: '//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js',
    complete: function () {
      if ( !window.jQuery ) {
            Modernizr.load('js/libs/jquery-1.7.1.min.js');
      }
    }
  },
  {
    // This will wait for the fallback to load and
    // execute if it needs to.
    load: 'needs-jQuery.js'
  }
]);

Modernizr.load의 확장은 http://yepnopejs.com에서 확인하자.

Modernizr를 이용한 감지

Modernizr의 속성은 모두 소문자로 이루어져 있으며 기본적으로 아래와 같은 포맷을 사용한다.

if(Modernizr.canvas) {
  //canvas supported
} else {
  //canvas not supported
}
속성 문법
Cnavas Modernizr.canvas
Canvas Text Modernizr.canvastext
HTML5 Video Modernizr.video
Video 포맷 if(Modernizr.video) { if(Modernizr.video.ogg) { //ogg 컨테이너의 오그 테오라 + 보비스를 시도하자 }else if(Modernizr.video.h264) {//MP4 컨테이너에 있는 H.264 비디오 + AAC 오디오를 시도하자}}
HTML5 Audio Modernizr.audio
History Management Modernizr.history
localstorage Modernizr.localstorage
webworker Modernizr.webworker
applicationcache Modernizr.applicationcache
geolocation Modernizr.geolocation
input type Modernizr.inputtypes.TYPE // TYPE = search, number, range, color, tel, url, email, date, month, week, time, datetime, datetime-local)
placeholder Modernizr.input.placeholder
autofocus Modernizr.input.autofocus
SVG Modernizr.svg
drag&drop Modernizr.draganddrop
microdata Modernizr에서는 지원하지 않는다.
if(Modernizr.input.placeholder == false){
  document.write('<script src="jquery.placeholder.js" type="text/javascript"></script>');
  $("input[placeholder]").placeholder();
}

html 요소에 붙는 class명과 대체방안

CSS 속성명 - Modernizr JS 오브젝트 속성(CSS 클래스명)

  • @font-face - fontface
  • background-size - backgroundsize
  • border-image - borderimage
  • border-radius - borderradius
  • box-shadow - boxshadow
    /* Simulated box shadow using borders: */
    .box {
      border-bottom: 1px solid #666;
      border-right: 1px solid #777;
    }
    
    .boxshadow div.box {
       border: none;
       -webkit-box-shadow: #666 1px 1px 1px;
          -moz-box-shadow: #666 1px 1px 1px;
                   box-shadow: #666 1px 1px 1px;
    }
    
  • Flexible Box Model - flexbox
  • hsla() - hsla

    대부분의 경우 rgba와 hsla 클래스는 브라우저가 fallback을 기본적으로 제공한다.

    .my_container {  /* no .hsla use necessary! */
      background-color: #ccc; /* light grey fallback */
      background-color: hsla(0, 0%, 100%, .5); /* white with alpha */
    }
    
  • Multiple backgrounds - multiplebgs
  • opacity - opacity
  • rgba() - rgba
  • text-shadow - textshadow

    IE9 이하는 text-shadow를 지원하지 않는다.

    .glowy { /* ghosted letters */
      color: transparent;
      text-shadow: 0 0 10px black;
    }
    .no-textshadow {
      color: black;
    }
    
  • CSS Animation - cssanimations

    Android 2.1-3 will pass this test, but can only animate a single property. Android 4+ behaves as expected.

  • CSS Columns - csscolumns
  • Generated Content (:before/:after) - generatedcontent
  • CSS Gradients - cssgradients

    WebKit은 배경 이미지의 불필요한 다운로드를 일으키는 버그가 있으며, CSS 그라데이션과 배경 이미지를 combo'ing하는 것이 가장 좋은 방법이므로, 여분의 HTTP 오버 헤드가 발생한다.

    .no-js .glossy,
    .no-cssgradients .glossy {
      background: url("images/glossybutton.png");
    }
    
    .cssgradients .glossy {
      background-image: linear-gradient(top, #555, #333);
    }
    
  • CSS Reflections - cssreflections
  • CSS 2D Transforms - csstransforms
  • CSS 3D Transforms - csstransforms3d
  • CSS Transitions - csstransitions

    좋은 사용 예는 애니메이션 엔진에 Modernizr를 구축하는 것이고 브라우저가 CSS transition 를 가지고 있다면 네이티브 CSS transition를 사용하는 것이고, 브라우저가 CSS transition을 사용 불가능하면 애니메이션을 자바스크립트로 구현하는 것이다.

Modernizr 실전 예제

원문 출처 : Taking Advantage of HTML5 and CSS# with Modernizr

홈페이지로부터 최신 버전을 다운로드한 후 웹페이지의 <head> 섹션에 아래와 같이 삽입한다.

<!DOCTYPE html> 
<html> 
  <head> 
    <meta charset="utf-8"> 
    <title>My Beautiful Sample Page</title> 
    <script src="modernizr-1.5.min.js"></script>
  </head> 
…

다음에 <html> 요소에 no-js 클래스를 추가해 준다.

<html class="no-js">

Modernizr가 실행되면 이 클래스가 js로 변경되어 웹브라우저에서 자바스크립트가 사용가능한 지 여부를 CSS로 알수 있도록 해준다. 또한 브라우저에서 감지되는 모든 속성에 대한 해당 클래스명을 추가해 주게 되는데, 브라우저가 지원하지 않는 속성에 대해서는 해당 클래스명 앞에 no-를 삽입해 주게 된다. 따라서 <html> 요소는 페이지 로드시에 자바스크립트가 사용가능할 경우 아래와 같이 보이게 된다.

<html class="js canvas canvastext no-geolocation rgba hsla multiplebgs borderimage borderradius boxshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions video audio localstorage sessionstorage webworkers applicationcache fontface">

Modernizr는 또한 Modernizr라는 자바스크립트 객체를 만들어, 각 속성에 대한 불린값을 가지는 속성목록 정보를 제공해 준다. 따라서 Modernizr.canvas 값은 브라우저가 canvas 요소를 지원하는 경우 true 값을 반환하고 그렇지 않은 경우에는 false 값을 반환하게 된다.

이 자바스크립트 객체는 특정 속성에 대한 상세정보까지도 제공해 주는데, 예를 들어, Modernizr.video.h264는 브라우저의 특정 코덱에 대한 지원여부를 알려준다. 또한 Modernizr.inputtypes.search는 search input 요소의 type에 대한 지원여부에 대해서 알려주게 된다.

이제 Modernizr를 적용하는 방법을 단계별로 알아 본다.

우선 보기에도 밋밋한 샘플 웹페이지를 하나 만든다. 그리고 여기에 약간의 스타일을 추가해 준다. 예를 들면, 보기 좋게하기 위해 전체적인 포맷이나 색상 그리고 레이아웃을 잡아 준다. 결과적으로 변경된 웹페이지는 이렇게 보일 것이다.

이제부터는 웹페이지의 기능을 추가해서 좀 더 흥미롭게 해 보자.

<h1> 요소에 임의의 폰트를 사용하고, Modernizr에서 이용가능한 속성들의 목록을 두개의 컬럼으로 배열하고, 이미지가 포함된 Modernizr 관련 내용을 오른쪽으로 이동한다. 그리고 웹페이지의 외곽선을 변경해서 더 멋지게 보이도록 한다. 이와 같이 CSS를 이용해서 새로운 속성(추가된 스타일)를 추가하게 되면 웹페이지는 더 완성도 있게 보이겠지만 만약 특정 브라우저가 이러한 속성들을 인식하지 못할 경우에는 해당 스타일을 무시한 채로 보이게 될 것이다.

CSS의 캐스케이딩 기술을 이용하면 Modernizr를 사용하지 않은 상태에서도 border-radius와 같은 것을 사용할 수 있다. 그러나, Modernizr를 사용할 경우에는 뭔가 추가적인 기능을 이용할 수 있게 된다. 즉, 특정 브라우저가 이와 다른 속성들을 지원하는 경우, 해당 속성을 원하는 데로 변경할 수 있게 된다는 것이다.

아래 두개의 CSS를 작성해서 예를 들어 본다.

.borderradius #content {
  border: 1px solid #141414;
  -webkit-border-radius: 12px;
  -moz-border-radius: 12px;
  border-radius: 12px;
}

.boxshadow #content {
  border: none;
  -webkit-box-shadow: rgba(0,0,0, .5) 3px 3px 6px;
  -moz-box-shadow: rgba(0,0,0, .5) 3px 3px 6px;
  box-shadow: rgba(0,0,0, .5) 3px 3px 6px;
}

첫번째 CSS는 #content 요소의 둥근 모서리의 크기를 12px로 추가해 준다. 그러나 이미 #content에 대해 2px outset #666로 외곽선을 지정한 바 있다. 이것은 외곽선의 모서리가 각이 저 있을 때에 어울려 보이지만 만약 둥근 모서리로 변경하게 되면 좀 어색하게 보이게 된다. 그러나 Modernizr 덕분에 특정 브라우저가 border-radius를 지원할 경우에만 외곽선을 1px solid로 렌더링하도록 할 수 있다.

두번째 CSS는 #content 요소에 drop shadow를 추가해 주고 특정 브라우저가 box-shadow 속성을 지원할 경우에는 외곽선을 제거해 준다. 왜 이렇게 해 주어야 할까?

대부분의 브라우저는 border-with-border-radius 조합을 렌더링하지 못하지만 box-shadow는 멋지게 렌더링해 주기 때문이다. 여기서는 외곽선만 사용하는 것 보다는 drop shadow를 사용하기로 한다. 이렇게 하므로써 모든 CSS를 최상의 상태로 보이게 할 수 있게 된다. 즉, box-shadow를 지원하는 브라우저는 drop shadow를 제대로 보여 줄 것이고, border-radius를 지원하는 브라우저는 얇은 외곽선과 함께 둥근 모서리를 보여주게 되며, 둘 다 지원하는 않는 경우에는 원래의 2px outset 외곽선을 보여 주게 되는 것이다.


다음에는 헤더 태그에 특정 폰트를 추가한다. 아래에 <h1> 요소에 대해 이미 선언해 놓은 내용을 보여 준다.

h1 {
  color: #e33a89;
  font: 27px/27px Baskerville, Palatino, "Palatino Linotype", "Book Antiqua", Georgia, serif;
  margin: 0;
  text-shadow: #aaa 5px 5px 5px;
}

이것은 제대로 동작하여 27px 크기의 폰트가 모든 폰트에 대해서 어울려 보이지만, Beautiful 이라는 폰트에 대해서는 상대적으로 작게 보이게 된다. 이 폰트를 사용하기 위해 아래와 같이 CSS를 추가한다.

@font-face {
  src: url(Beautiful-ES.ttf);
  font-family: "Beautiful";
}

.fontface h1 {
  font: 42px/50px Beautiful;
  text-shadow: none;
}

우선 @font-face 선언을 통해서 추가한 폰트를 위해 path, filename, font-family 속성를 지정해 준다. 그리고 <h1> 요소에 추가한 폰트를 사용하도록 지정해 주는데 훨씬 큰 폰트 크기로 할당해 준다. 이렇게 한 이유는 추가하게 되는 Beautiful 폰트가 h1 요소에 지정한 다른 폰트에 비해 훨씬 작게 렌더링되기 때문이며 따라서 이 폰트를 렌더링할 때만 브라우저가 헤더 태그를 훨씬 크게 렌더링하도록 해 주어야 하기 때문이다.

여기에 더해서, Beautiful 폰트는 text shadow를 표시하는데 약간 문제를 가지고 있어서 브라우저가 이 폰트를 렌더링할 때 shadow를 제거했다. Modernizr의 feature들에 대한 목록을 두 컬럼으로 분리할 필요가 있다. 이를 위해서, CSS columns를 사용할 것인데 브라우저는 해당 목록의 순서를 유지한 채 두 컬럼으로 재배열하게 된다. 숫자로 순서를 표시하지는 않았지만 이 목록은 알파벳순으로 배열된다. 물론, 모든 브라우저가 아직 CSS columns를 지원하지 않아서 이 경우에는 float 속성을 이용하게 되는 이 때는 더 이상 알파벳순으로 소팅되지 않지만 하나의 컬럼으로 보이는 것보다는 더 낫게 보이게 된다.

.csscolumns ol.features {
  -moz-column-count: 2;
  -webkit-columns: 2;
  -o-columns: 2;
  columns: 2;
}

.no-csscolumns ol.features {
  float: left;
  margin: 0 0 20px;
}

.no-csscolumns ol.features li {
  float: left;
  width: 180px;
}

다시 Modernizr를 이용한다. 이때는 속성 변경이나 캐스케이딩을 이용하여 해결할 수 없는 경우에만 자주 사용하는 속성을 적용하기로 한다. 브라우저가 CSS columns를 지원할 경우에는 문제없이 원하는 결과를 얻을 수 있지만, 그렇지 못할 경우에는(<html> 요소에 "no-csscolumns" CSS 클래스가 추가되어 알 수 있다), 이 목록 항목들을 float 해서 비슷하게 보이도록 margin과 width를 변경해 준다. 이것은 좋은 방법은 아니지만 길다란 목록을 보는 것보다는 낫다는 것이다.

이미 눈치챗을 수도 있지만, 이전 예제에서 사용했던 border-radius와 box-shadow 속성과는 다르게 columns를 지정하게 되는데, 오페라(Opera) 브라우저만이 현재 vendor 명을 앞에 붙인 상태로 CSS columns를 지원하고, 모질라(Mozilla)의 경우는 아직까지 "columns"라는 단축형의 속성을 인식하지 못해서 -moz-column-count 속성을 사용해야 하기 때문이다.


지금까지 작업한 변경내용을 이와 같이 볼 수 있다.

마지막으로 훨씬 더 세련된 기능을 추가해 보도록 한다. WebKit 기반의 브라우저들은 CSS transitions, animations, 3D transforms 같은 멋진기능들을 지원하는데 여기서 몇가지를 적용해 보도록 한다. 이것들 중에 몇가지 속성은 간단하게 추가할 수 있고 이를 지원하지 않는 브라우저에서는 별문제없이 무시되는데, 그러나 어떤 속성은 이와 같이 추가하게 되면 모든 브라우저의 레이아웃이 깨져 버리는 사태가 발생할 수 있는데 Modernizr를 사용하면 이런 경우를 효과적으로 조절할 수 있게 된다.

먼저 아래와 같이 설정을 한다.

@-webkit-keyframes spin {
   0% { -webkit-transform: rotateY(0); }
 100% { -webkit-transform: rotateY(360deg); }
}
.csstransforms3d.cssanimations section {
 -webkit-perspective: 1000;
}

@keyframes는 새롭게 추가된 CSS animations 스펙 중에 하나인데, 현재는 WebKit 류의 브라우저에서만 지원한다(이 글의 작성일시는 꽤나 오래되어서 그렇고 현재는 최신의 브라우저들은 모두 지원한다). 이것은 원하는 속성만으로도 전체 animation을 선언할 수 있는데 원하는 스텝에서 변경작업도 수행할 수 있다.

CSS로 animation을 적용하고자 할 때 duration, loop count, easing curves들을 지정해 줄 수 있지만, 여기서는 duration은 지정하지 않고 key frames 만 지정했다는 것에 주목해야 한다. 이렇게 하므로써 다른 엘리먼트에 대해서는 다른 속도를 지정하여 특정 animation을 재사용할 수 있어 유연성을 극대화 할 수 있다. animations에 대한 더 자세한 정보는 W3C Working Draft specification을 참고하면 된다.

다음은, 3차원 공간에서 엘리먼트를 회전할 수 있도록 <h2> 요소에 animation을 적용한다.

.csstransforms3d.cssanimations section h2 {
  background-image: url(modernizr-logo.png);
  overflow: hidden;
  -webkit-animation: spin 2s linear infinite;
}

여기서는 3차원 공간에서 이미지를 회전시킬 것이기 때문에, 배경이미지로 앤티앨리어스 처리된 멋진 Modernizr 로고를 사용하기 위해 PNG 버전으로 교체할 것이다. 또한 헤더내의 텍스트를 감추기 위해 overflow: hidden 속성을 추가하고 오프셋을 -9999px 설정해서 보이지 않게 해 준다. 3차원 공간에서 엘리먼트를 회전시키면 회전하는 동안 보이게 되는데 놀랍지만 그렇게 멋지게 보이지 않았다. 마지막으로, animation을 적용해서 2초로 세팅하고 선형 패션으로 무한루프로 회전하게 한다.

최종 웹페이지는 이와 같이 보이게 된다. WebKit 류 브라우저에서는 재밌는 animation이 보이게 된다. 바란건대 Modernizr를 이용하므로써 웹사이트 훨신 잘 제어할 수 있고 점직적인 기능향상을 잘 구현할 수 있기를 바란다. 여기서 설명한 것이 Modernizr의 모든 것이 아니지만 자바스크립트로 구동된 fallback을 생성하고 HTML5의 새롭고 멋진 속성들을 사용하는데 매우 중요한 내용이 될 것이다.