傳統瀏覽器目前不會被完全取代,讓你難以將最新的 CSS3 或 HTML5 功能嵌入你的網站。 Modernizr 正是為解決這個難題應運而生,作為一個開源的 JavaScript 函式庫,Modernizr 偵測瀏覽器對 CSS3 或 HTML5 功能支援。 Modernizr 並非試圖加入舊版瀏覽器不支援的功能,而是令你透過建立選用風格配置來修改頁面設計。 它也可以透過載入自訂的腳本來模擬舊版瀏覽器不支援的功能。
什麼是Modernizr?
Modernizr是一個開源的JS庫,它使得那些基於訪客瀏覽器的不同(指對新標準支持性的差異)而開發不同級別體驗的設計師的工作變得更為簡單。它使得設計師可以在支援HTML5和CSS3的瀏覽器中充分利用HTML5和CSS3的特性進行開發,同時又不會犧牲其他不支援這些新技術的瀏覽器的控制。
當你在網頁中嵌入Modernizr的腳本時,它會偵測目前瀏覽器是否支援CSS3的特性,例如@font-face、border-radius、 border-image、box-shadow、rgba() 等,同時也會偵測是否支援HTML5的特性-例如audio、video、本地儲存、和新的標籤的類型和屬性等。在獲取到這些資訊的基礎上,你可以在那些支援這些功能的瀏覽器上使用它們,來決定是否創建一個基於JS的 fallback,或者對那些不支援的瀏覽器進行簡單的優雅降級。另外,Modernizr還可以令IE支援對HTML5的元素套用CSS樣式,讓開發者可以立即使用這些更富有語意化的標籤了。
Modernizr 簡單易用,但不是萬能的。 成功使用 Modernizr 很大程度取決於你的 CSS 和 JavaScript 技能。
使用HTML 5和CSS 3的主要問題不是普及程度和瀏覽器之間的差異,而是首先了解這些差異是什麼。一旦搞清楚,開發人員就能夠採用優雅降級(graceful degradation)技術來解決這些限制。為此,許多開發人員求助於開源專案Modernizr。
Modernizr不是偵測user-agent字串,而是使用一系列測試來判斷瀏覽器的特性。在幾毫秒內它就能夠執行超過40種測試並將結果作為屬性記錄在名為Modernizr的物件中。開發人員可以透過這些資訊來偵測他們準備使用的某一特性是否被瀏覽器支援並作出相應的處理。
在Modernizr 2.0版中, 它增加了一個針對JavaScript和CSS的條件資源載入器(conditional resource loader)。此資源載入器接受三個參數,第一個是表達式,列舉了所需的特性。第二個參數是如果表達式回傳true則載入的JavaScript和 CSS檔案清單。第三個參數是所需特性不存在的情況下備用的檔案清單。
除了優雅降級,加載器還可用於引入polyfill。 請容許我向那些還不太熟悉pollyfill的朋友解釋一下,pollyfill是「一種JavaScript墊片(shim),為舊版瀏覽器模擬了標 準API」。雖然這種方式不總是值得推薦,但是pollyfill能夠用來添加(Modernizr檢測到的)大多數HTML 5特性的支援。這裡,polyfill 用來填補瀏覽器功能上的漏洞。 有時,Modernizr 可無縫地執行這項任務。 但本質上,這只是一種修補工作,所以,不能依賴它產生無漏洞瀏覽器所實現的完全相同結果。
為了改善效能,開發人員可以客製化Modernizr來執行網站所需的測試。這可以透過Modernizr下載頁面來完成,該頁面同時顯示了能夠偵測的特性清單。在github網站上也標示著無法偵測的特性和可能的解決方案。
Modernizr是基於漸進式增強理論來開發的,所以它支援並鼓勵開發者一層一層的創建他們的網站。一切從一個應用了Javascript的空閒地 基開始,一個接一個的添加增強的應用層。因為使用了Modernizr,你很容易知道瀏覽器都支援什麼。
Modernizr的原理
Modernizr 使用 JavaScript 偵測瀏覽器所支援的功能,但是,它並不是使用 JavaScript 動態地載入不同的樣式表,而是使用非常簡單的技術將類別新增至頁面的標籤。然後作為設計者由你決定使用 CSS 層疊為目標元素提供合適的樣式。
例如,如果頁面支援 box-shadow 屬性,那麼 Modernizr 會加入 boxshadow 類別。如果不支持,那麼它用 no-boxshadow 類作為替代進行添加。
由於瀏覽器忽略它們無法識別的CSS 屬性,因此你可以放心地按照你的基本樣式規則使用 box-shadow 屬性,然而需要按照下面的格式為舊版本的瀏覽器添加單獨的 descendant selector :
.no-boxshadow img { /* styles for browsers that don't support box-shadow */ }
只有不支援 box-shadow 的瀏覽器才會有 no-boxshadow 類,因此其它的瀏覽器不會套用這個樣式規則。
下表列舉了 Modernizr 使用的類別名稱以表示對 CSS3 的支援。 如果某個功能不支持,那麼對應類別的名稱用no-作前綴。
CSS 功能 |
Modernizr 類別(屬性) |
@font-face | 字型 |
::before 和 ::after 偽元素 | 產生的內容 |
背景大小 | 背景大小 |
邊框影像 | 邊框影像 |
邊界半徑 | 邊界半徑 |
盒子陰影 | boxshadow |
CSS 動畫 |
css動畫 |
CSS 2D 轉換 |
css 轉換 |
CSS 3D 轉換 |
csstransforms3d |
CSS 過渡 |
CSS 過渡 |
靈活的盒子佈置 |
彈性盒 |
漸層 |
css漸層 |
hsla() | hsla |
多列佈局 |
css 欄位 |
多種背景 |
多bgs |
不透明度 | 不透明度 |
反思 |
CSS反射 |
rgba() | rgba |
文字陰影 | 文字陰影 |
無論在哪對特定的CSS屬性進行測試,類別的名稱和屬性名稱都是一樣的,然而這要求去除任何連字號或是括號。 其它類別是按照它們參考的CSS3模組而命名。
Modernizr的使用
1. 下載
首先從www.modernizr.com下載Modernizr的最新的穩定版。把它加入頁面的
區域:2. 在元素上加上「no-js」的類別
當Modernizr運行的時候,它會把這個「no-js」的類別變成「js」來讓你知道它已經運行。 Modernizr並不僅僅只做這一件事情,它還會為所有它檢測過的特性添加class類,如果瀏覽器不支援某個特性,它就為該特性對應的類名加上「no-」的前綴。
加入no-js class到html元素下,是告訴瀏覽器是否支援JavaScript,如果不支援就顯示no-js,如果支援就把no-js刪除
此時如果使用Dreamweaver 的Live Code,可以看到Modernizr增加了大量的表明瀏覽器功能的類,如下圖
如圖所示, no-js 類別已經被js類別取代,這表示 JavaScript 已經啟用。
如果你的 Dreamweaver 版本沒有 Live Code(或你正在使用不同的 HTML 編輯器),那麼你可以使用大多數新式瀏覽器提供的開發工具或 Firefox 瀏覽器提供的 Firebug 檢查產生的程式碼。
3. 使用案例1-在支援shadow陰影的瀏覽器顯示shadow,不支援的瀏覽器顯示標準的邊框
因為如果瀏覽器支援box-shadows的話,Modernizr就會將boxshadow class加入元素,然後你可以將它管理到一個對應的div的id上。如果不支持,Modernizr就會將no- boxshadow class加入元素,這樣顯示的就是一個標準的邊框。這樣我們就可以很方便地在支援CSS3特性的瀏覽器上使用CSS3新功 能,不支援的瀏覽器上繼續使用以前的方式。
4. 使用案例2——測試本地儲存
Modernizr除了加入對應的class到元素以外,還提供一個全域的Modernizr JavaScript對象,該對象提供了不同的屬性來表示某種新特性在目前瀏覽器下是否支援。例如,下面的程式碼可以用來判斷瀏覽器是否支援canvas和 local storag。對於多個開發人員在多版本瀏覽器下開發測試的時候很有好處的。
<script> window.onload = function () { if (localStorageSupported()) { alert('local storage supported'); } }; function localStorageSupported() { try { return ('localStorage' in window && window['localStorage'] != null); }catch(e) {} return false; } </script>
大家可以統一代碼
$(document).ready(function () { if (Modernizr.canvas) { //Add canvas code } if (Modernizr.localstorage) { //script to run if local storage is } else { // script to run if local storage is not supported } });
全域的Modernizr物件也可以用來偵測是否支援CSS3特性,以下的程式碼用來測試是否支援border-radius 和CSS transforms:
$(document).ready(function () { if (Modernizr.borderradius) { $('#MyDiv').addClass('borderRadiusStyle'); } if (Modernizr.csstransforms) { $('#MyDiv').addClass('transformsStyle'); } });
audio 和 video 而言,傳回值是一個字串,它表示著瀏覽器能夠處理特定類型的置信水準。 根據 HTML5 規範,空的字串表示該類型不支援。 如果支援該類型,那麼傳回值是「maybe」或是「probably」。 例如:
if (Modernizr.video.h264 == "") { // h264 is not supported }
4. 使用案例3——使用 Modernizr 驗證 HTML5 必需的表單欄位
HTML5 新增了許多新的表單屬性,例如 autofocus,當頁面第一次載入時它會自動地將遊標放在某個指定的欄位。 另一個有用的屬性是 required, 如果某個必需的欄位留有空白,那麼它將阻止HTML5相容的瀏覽器提交表單。
圖1. 腳本偵測到不支援新屬性的瀏覽器中的必要欄位
圖2. 腳本偵測到不支援新屬性的瀏覽器中的必要欄位
提交表單前,HTML5 相容的瀏覽器會檢查必需欄位是否已填寫
window.onload = function() { // get the form and its input elements var form = document.forms[0], inputs = form.elements; // if no autofocus, put the focus in the first field if (!Modernizr.input.autofocus) { //因如果不支持 autofocus,那么该条件的求值结果为 true,并且 inputs[0].focus() 将光标放在第一个输入字段 inputs[0].focus(); } // if required not supported, emulate it if (!Modernizr.input.required) { form.onsubmit = function() { var required = [], att, val; // loop through input elements looking for required for (var i = 0; i < inputs.length; i++) { att = inputs[i].getAttribute('required'); // if required, get the value and trim whitespace if (att != null) { val = inputs[i].value; // if the value is empty, add to required array if (val.replace(/^\s+|\s+$/g, '') == '') { required.push(inputs[i].name); } } } // show alert if required array contains any elements if (required.length > 0) { alert('The following fields are required: ' + required.join(', ')); // prevent the form from being submitted return false; } }; } }
程式碼產生了一個函數,當提交表單時它能夠遍歷所有的輸入元素,以便於找到具有 required 屬性的欄位。 當它找到某個欄位時,它會從值中除去開頭和結尾的空白,並且如果結果是一個空的字串,那麼它會把結果加到 required 數組中。 在所有的欄位都已經被檢查後,如果陣列中包含某些元素,那麼瀏覽器會顯示一個與缺失欄位名稱有關的警告,並阻止提交表單。
建立自訂版本
當你準備好對你的網站進行部署時,推薦創建一個 Modernizr 的自訂 production 版本,它只包含那些你實際需要的元素。 這可以依照你所選的功能將 Modernizr 函式庫的大小從 44KB 縮小到 2KB。目前選項的範圍如圖所示。
參考: