響應式 Web 設計技巧

什麼是響應式設計?

iOS 和 Android 的發佈,智能手機、平板電腦、智能家電等新設備層出不窮,極大便利了咱們的生活,但面對形形色色的終端設備,千差萬別的屏幕分辨率,給網頁設計帶來了新的挑戰,咱們沒法估計用戶的終端設備和網絡情況,更不可能爲每種設備都專門設計一套網站,如何實現 Web UI 在多終端中的適配呢?2010 年 Ethan Marcotte 曾經在 A List Apart 發表過一篇文章"Responsive Web Design",響應式網頁設計提供了一種設計方法,可使同一網站在智能手機、桌面電腦,以及介於這二者之間的任意設備上完美顯示。這種方法可以根據用戶的屏幕尺寸,合理地爲現有及未來的各類設備提最佳的瀏覽體驗。php

http://mediaqueri.es/ 這是一個響應式設計創意收集網站,能夠在上面查看到不少響應式設計實例,較多的網站都應用了 Mobile First 設計思想,先針對小視口設備進行設計,而後逐步對大視口設計進行漸進加強支持。css

圖 1. Froont 響應式設計網站截屏

Froont 響應式設計網站截屏

這也意味着設計思惟的轉換,不該再執着於佈局、線框等的具體大小,而應該考慮如何使用流體元素。與其根據不一樣設備的大小來設計頁面,更着重考慮如何針對內容進行設計。拋棄像素,拋棄固定寬度,先從小屏幕進行設計,而後逐步加強針對大屏幕的設計前端

固然也須要引導客戶,網站沒必要在全部瀏覽器中表現一致,時間應該花在更有價值的地方,而不是花大量時間修復爛瀏覽器固有的缺陷。核心思想就是,優雅降級,內容優先。css3


響應式設計是最佳選擇嗎?

實際項目中,何時咱們須要用到響應式設計呢?並不是全部的頁面呈現,內容設計問題均可以經過響應式設計思路解決,項目的預算、目標用戶及定位決定了其實現方式。git

舉幾個例子來講,若是一個提供促銷內容的網站,咱們能夠經過 CSS3 媒體查詢技術,根據視口大小爲用戶提供與之匹配的視覺效果,迎合小屏幕的同時兼容超大屏幕,不一樣的視覺展現方式來響應各類設計大小,提供更好的用戶體驗和無歧視的設計,好比爲小屏幕提供更容易手指操做的設計同時,爲超大屏幕提供內容也能提供額外改進,這時響應式設計是優選。若是是一個預算充足的點餐網站,定製一個真正的「手機移動版」更爲合適,用戶可基於 GPS 找到附近的店家點餐,或者是一個 dashboard 網站,有大量的數據內容和管理命令,此時單獨的響應式設計方案遠遠不能支撐這種解決方案。任何工具或技術都應該只在應用程序須要它的時候使用,IE 7 和 8 不支持 HTML五、CSS3 的新屬性。若是一個網站的絕大多數用戶都使用 IE 7 或 8,或更低版本,作成響應式意義也不大,但不表明作不到。github

總結下來,響應式設計的優勢是靈活性強,適應不一樣分辨率的設備,缺點是兼容各類設備致使代碼臃腫,加載時間加長。web

選擇在現有代碼基礎上的加強的折中性響應式設計?仍是選擇一個真正的「手機版」,要依賴於項目實際狀況。bootstrap


什麼是視口(viewport)和屏幕尺寸(screen.width)?

視口和屏幕尺寸不是同一個概念。視口(viewport),便可視區域的大小,是指瀏覽器窗口內的內容區域,不包含工具欄、標籤欄等。也就是網頁實際顯示的區域。屏幕尺寸指的是設備的物理顯示區域,用戶屏幕的總體大小。跨域


視口調試工具

在 IE 下,可以使用 MS IE developer toolbar, Chrom 自帶的調試工具也能很方便的進行視口調試。Safari 用戶可選擇 ResizeMe 或 Resize, Firefox 用戶可使用 Firesizer.瀏覽器

圖 2. IE Developer Toolbar 視口調試截圖

IE Developer Toolbar 視口調試截圖

圖 3. Firesizer 視口調試工具截圖

Firesizer 視口調試工具截圖

響應式 Web 設計工做原理

應用 CSS3 的媒體查詢(Media Queries),建立一個包含適應各類設備尺寸樣式的 CSS。一旦頁面在特定的設備上加載,此時,會先檢測設備的視口大小,而後加載特定於設備的樣式。即爲不一樣的媒體類型設定專有的樣式表。

建立媒體查詢

如下代碼演示了一個最爲簡單的媒體查詢實例,瀏覽此頁面並不斷調整瀏覽器窗口寬度。頁面的背景顏色就會根據當前的視口尺寸而發生變化。CSS 屬性用於聲明如何表現頁面背景顏色切換,而 Media Query 語句是判斷輸出設備的最大視口寬度是否知足某種條件的條件表達式。

清單 1. 基本媒體查詢代碼
body {
background-color: grey;
}
@media screen and (max-width: 960px) {
body {
background-color: red;
}
}
@media screen and (max-width: 768px) {
body {
background-color: orange;
}
}
@media screen and (max-width: 550px) {
body {
background-color: yellow;
}
}
@media screen and (max-width: 320px) {
body {
background-color: green;
}
}

目前 Firefox 3.6+、Safari 4+、Chrome 4+、Opera 9.5+、iOS Safari 3.2+、Opera Mobile 10+、Android 2.1,IE9+ 都支持媒體查詢。

圖 4. 兼容 Media Query 的瀏覽器彙總

兼容 Media Query 的瀏覽器彙總

IE8 及如下的老版本並不支持 Media Query 查詢,但也能夠引入 polyfill 腳本(膩子腳本 polyfill 就是一大堆五花八門技術的集合,目的就是填平舊瀏覽器對 HTML五、CSS3 支持上的缺陷),基於 JavaScript 實現兼容修復, 引入 Respond.js(https://github.com/scottjehl/Respond)或 css3-mediaqueries.js(https://github.com/livingston/css3-mediaqueries-js)能夠解決這個問題。

清單 2. 爲 IE 老版本引入膩子腳本
<!--[if lt IE 9]> 
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> <![endif]-->


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


respond.js 和 css3-mediaqueries.js 的比較

respond.js 介紹

優點:

  1. 體積小,速度快。

  2. 可靠!bootstrap 3 也引用了 respond.js。

  3. 不依賴其餘腳本或庫,併爲移動端作了優化(respond.min.js 只有 1kb)


劣勢:

  1. 僅支持 min-width 和 max-width。

  2. Respond.js 不解析經過@import 引用的 CSS 也不解析包含在 style 標籤內聯的 media queries,由於這些樣式不能從新請求解析。


提示:

  1. 引用 respond.js 時,請放到全部 CSS 文件以後(越早運行它,IE 用戶不容易看到非 media 內容的閃爍)

  2. respond.js 經過 Ajax 請求一個您的 CSS 的原始副本,若是您部署您的樣式文件在 CDN 上(或者子域名下),您須要上傳一個代理頁面來實現跨域通訊。

  3. 由於安全的限制,一些瀏覽器可能不容許這個腳本在 file://ruls 裏起做用(由於他使用 XMLHTTPRequest)。

總結:它不是惟一的 CSS3 媒體查詢膩子腳本,可是它多是最快的。

css3-mediaqueries.js 介紹

優點:

  1. 更健壯,支持不少 media query 特性,支持 px 和 em

  2. 實時響應


劣勢:

  1. 體積較大(15kb) ,運行較慢

  2. 不支持 width

  3. 不支持 @import

  4. 對 <link> 和 <style> 標籤內的 media 屬性無效

總結:當渲染複雜的響應性設計時,它能支持不少 media query,但運行明顯緩慢。


CSS3 媒體查詢(Media Query)詳細介紹

HTML4 和 CSS 2 中能夠經過<link>標籤的 media 屬性爲樣式表指定設備類型,有八種,screen 和 print 是兩種最多見的媒體類型,舉例說明,如下代碼爲不一樣的設備指定加載不一樣的樣式文件,實際應用好比說,一個頁面在屏幕上顯示時使用無襯線字體,而在打印時則使用襯線字體以顯示更好的可讀性,或一個頁面在屏幕上顯示時有廣告,打印時去除廣告,均可經過 media 屬性來分別加載匹配的 CSS 文件解決。

<link rel="stylesheet" type="text/css" media="screen" href="screen.css">

<link rel="stylesheet" type="text/css" media="print" href="print.css" />

CSS3 中的 Media Queries 增長了更多的媒體查詢,在 CSS3 中咱們能夠設置不一樣類型的媒體條件,並根據對應的條件,給相應符合條件的媒體調用相對應的樣式表。您能夠把媒體查詢語句想象爲條件表達式,舉例說明:

<link rel="stylesheet" media="screen and (orientation: portrait)"  href="portraitscreen.css" />

您是一塊縱向的顯示屏嗎?

<link rel="stylesheet" media="not screen and (orientation: portrait)"  href="portraitscreen.css" />

追加 not 顛倒該查詢的邏輯

<link rel="stylesheet" media="screen and (orientation: portrait) and (min-width:
800px)" href="800wide-portrait-screen.css" />

視口寬度大於 800px 的縱向顯示屏

<link rel="stylesheet" media="screen and (orientation: portrait) and (min-width:
800px), projection" href="800wide-portrait-screen.css" />

只要是 projection 就爲真,所有查詢都不爲真,則不加載

@media screen and (max-device-width: 400px) {h1{color:red}

媒體查詢也能夠寫到樣式表中

@import url("phone.css") screen and (max-width:360px);

也有不常見的寫法,是在 CSS 樣式表中用@import 在當前樣式表中引用其餘樣式表。但須要注意的是慎用 CSS 的@import ,會影響加載速度。

關於 link vs @import 題外話

咱們能夠經過 link 和@import 兩種方式引入 CSS 文件

清單 3. 引入 CSS 方式
<link rel='stylesheet' href='a.css'>

或

<style>
@import url('a.css');
</style>

兩者之間的差異是:

Link 採用 HTML 標籤將 CSS 關聯,而 import 能夠在一個 CSS 文件中引入其它的 CSS 文件

兼容性的差異。IE6 如下不支持@import

加載順序的差異(詳細請參見:http://www.stevesouders.com/blog/2009/04/09/dont-use-import/)

4)JS 控制 DOM 樣式時的差異(link 支持使用 Javascript 控制 DOM 去改變樣式;而@import 不支持)

實際項目經驗是,@import 在 IE 中會致使文件下載次序被更改,例如放置在@import 後面的 script 文件會在 CSS 以前被下載執行,若此時腳本里 getElementsByClassName 時則出錯。


響應式設計前提

響應式設計理念是基於流動佈局、彈性圖片、彈性表格、彈性視頻和媒體查詢等技術的組合。使用百分比佈局建立流動的彈性界面,同時使用媒體查詢來限制元素的變更範圍,這二者組合到一塊兒構成了響應式設計的核心。而固定寬度像素的佈局沒法實現多變的,未知的設備。

關於流動佈局,它是一種適應屏幕的作法,即不固定 DIV 的寬度,而是採用百分比做爲單位來肯定每一塊的寬度。具體採用的方式就是棄用 px,改用 em 或%爲單位,早期咱們此方式是爲了文字縮放,確保老版本的 IE 也能調節字體大小。您可能會有疑問,既然現代瀏覽器好久之前就支持縮放以像素爲單位的文字,那麼用 em 的優越性又體如今哪裏呢?最大的優點是,當咱們用相對單位 em 來寫佈局和字體大小時,若是咱們給<body>標籤設置文字大小爲 100%,給其餘文字都使用相對單位 em,那這些文字都會受 body 上的初始聲明的影響。這樣您能夠批量修改頁面文字和佈局,相對更爲靈活。缺點是可能在百分比的計算上不如像素那樣簡單直接,將像素轉爲 em 的訣竅在於,Dan Cederholm 寫過一篇關於流式佈局裏文章裏提到一個公式,目標元素尺寸÷上下文元素尺寸=百分比尺寸,並不能簡單的把目標元素理解成子元素,把上下文元素理解成父級元素,雖然大多數時能夠這麼理解,但上下文元素並不必定表明父級元素,舉例說明以下:

若是一個實際 PSD 設計稿是採用固定像素設計的,940px 的 header 層被包含在 960px 的 wrapper 層裏。

圖 5. PSD 設計稿舉例

PSD 設計稿舉例

wrapper 層內包裹 header 層,按 px 寫法是:

清單 4. 固定寬度設計代碼示例
#wrapper {
margin-right: auto;
margin-left: auto;
width: 960px;
}
#header {
margin-right: 10px;
margin-left: 10px;
width: 940px;
}

轉成百分比後,應該這麼寫,此時的上下文元素就是父級元素:

清單 5. 百分比寬度設計代碼示例
#wrapper {
margin-right: auto;
margin-left: auto;
width: 90%; /* 控制最外層的 div,這個值能夠是 100%, 90%或者其它您認爲實際頁面顯示最佳的一個百分比*/
}
#header {
margin-right: 10px;
margin-left: 10px;
width: 97.9166667%; /* 940 ÷ 960 */
}

再舉例說明,以下 HTML 結構

<h1>測試<span>上下文</span></h1>

CSS 樣式爲:
h1 {font-size: 4.3125em; } /* 69 ÷ 16 */
#content h1 span {
font-size: .550724638em; /* 38 ÷ 69 */
line-height: 1.052631579em; /* 40 ÷ 38 */
}

默認瀏覽器文字大小是 16px,假設設計稿裏 h1 爲 69px, span 爲 38px,line-height 爲 40px,能夠看到<span>元素的文字大小(38px)是相對於其父元素的文字大小(69px)而言的,而它的行高(40px)則是相對於其自己的文字大小(38px)而言,因此咱們不能一律而論認爲上下文元素就是等同於父級元素。

總結;流式佈局是響應式設計的基礎和起點。


開始動手製做一個響應式網站吧

以這樣一個頁面佈局爲例,分別在最大寬度爲 980px、700px 和 480px 時改變其佈局:

圖 6. 頁面佈局示例

頁面佈局示例


第一步:Meta 標籤或@viewport{}

<meta name="viewport" content="width=device-width, initial-scale=1.0">

Intial-scale=1.0 即阻止移動瀏覽器自動調整頁面大小 ,表示瀏覽器將按照其視口的實際大小來渲染頁面。

咱們也可使用@viewport 規則控制 viewport,與使用 meta 標籤的效果相同,只是徹底使用 CSS 來控制。zoom 描述符等同於 viewport meta 標籤的 initial-sacale 屬性。

@viewport {
width: device-width;
zoom: 1;
}

第二步:爲 IE8 和如下版本添加支持媒體查詢的 JS,能夠用 media-queries.js 或 respond.js

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

第三步:編寫頁面 HTML 結構

/* STRUCTURE */
#pagewrap {
width: 960px;
}
#header {
height: 180px;
}
#content {
width: 600px;
float: left;
}
#sidebar {
width: 300px;
float: right;
}
#footer {
clear: both;
}

第四步:編寫媒體查詢語句

當視口寬度爲 980px 及如下時定義了百分比寬度,當視口寬度爲 700 及如下時,去除寬度和浮動,此時 content 和 sidebar 將佔滿整個寬度,當視口寬度爲 480 及如下時,縮小 h1 標題的字體大小,隱藏 sidebar,以更好的適應小屏幕有限空間。代碼以下:

/* for 980px or less */
@media screen and (max-width: 980px) {

#pagewrap {
width: 95%;
}
#content {
width: 65%;
}
#sidebar {
width: 30%;
}

}
/* for 700px or less */
@media screen and (max-width: 700px) {

#content {
width: auto;
float: none;
}
#sidebar {
width: auto;
float: none;
}

}

/* for 480px or less */
@media screen and (max-width: 480px) {

h1 {
font-size: 0.8em;
}
#sidebar {
display: none;
}

}

(以上代碼參考文章:http://webdesignerwall.com/tutorials/responsive-design-in-3-steps)


媒體查詢語句寫在哪最爲合適?

將不一樣的媒體查詢樣式保存到獨立的文件中,我的認爲沒有太大的好處,由於多個獨立的文件會增長用於頁面渲染的 HTTP 請求數量,從而致使頁面加載變慢,事實上這樣處理也並未更便於組織代碼,而極容易遺漏部分媒體查詢語句。

建議在已有的樣式表中追加媒體查詢樣式。在主樣式後面緊隨媒體查詢語句的一個好處是,當主樣式有所更改時,媒體查詢樣式頗有可能也須要作相應的調整,這樣您不容易遺漏。如:

#header h1{}
@media screen and (max-width: 768px) {#header h1{}}方法。

窗體底端


怎麼設置斷點?

傳統的肯定斷點的方案是使用一些固定的寬度進行劃分,如 320px(iPhone),768px(iPad),960px 或 1024px(傳統 PC 瀏覽器),這種方案的好處是很好照顧到了當前主流的設備,可是技術發展實現是太快了,各類不一樣分辨率的設備層出不窮,好比一些手機尺寸接近平板,一些平板尺寸比電腦更大等等,很難保證將來能很好的支持各類設備。另一種肯定斷點的方法是根據內容進行設置斷點以及設置多少個斷點。隨着各類尺寸設備的出現,斷點命名採用更爲通用的方式,而不是用設備來命名更爲合適。

圖 7. 斷點設置參考

斷點設置參考


響應式圖片

實現圖片隨着流動佈局相應縮放很是簡單。須要在 CSS 中聲明:

img { max-width: 100%; }

這樣就可使圖片自動縮放到與其容器 100%匹配。咱們能夠將一樣的樣式應用到其餘多媒體標籤上。如:

img,object,video,embed {max-width: 100%;}

圖片能夠隨着視口的伸縮而縮放了,可是若是將視口拉大(好比 1900px),直到圖片拉伸至超出其原始尺寸,那麼圖片頗有可能也被拉寬,必須追加一句 CSS 聲明:

.img{max-width: 202px;}


咱們也能夠給最外層#wrapper 來設置 max-width 來限制流體佈局頁面被拉大,如:

清單 6. 響應式圖片代碼示例
#wrapper {
margin-right: auto;
margin-left: auto;
width: 96%;
max-width: 1414px;
}

那麼問題來了?這樣算完成了圖片的響應嗎?答案是否認的。彈性圖片並不等於響應式圖片。咱們應該爲不一樣的屏幕尺寸提供不一樣的圖片。以下所示,再也不是一張圖片知足不一樣的設備,而是爲大屏幕準備大尺寸圖片,小屏幕準備尺寸更小的清晰圖片。

圖 8. 一張圖片應用在不一樣尺寸的設備上

一張圖片應用在不一樣尺寸的設備上

圖 9. 針對不一樣的設備應用不一樣的圖片

針對不一樣的設備應用不一樣的圖片


推薦二種響應式圖片解決方案以下:

Matt Wilcox 解決方案

  1. 把.htaccess 和 adaptive-images.php 放根目錄

  2. 建立一個可寫入的緩存文件夾

  3. <script>document.cookie='resolution='+Math.max(screen.width,screen.height)+'; path=/';</script>

Sencha.io Src解決方案:<img src="http://src.sencha.io/http://mysite.com/images/my-image.jpg" />


響應式視頻

不一樣與以往須要插入視頻須要一段臃腫的代碼,HTML5 插入視頻只須要一行代碼,但問題是它不是響應的。

<video src="Video.ogg"></video>

注意:Safari 只容許在<video>和<audio>元素中使用 MP4/H.264/AAC 媒體文件,而 Firefox 和 Opera 則只支持 Ogg 和 WebM,因此更爲完整的寫法以下:

清單 7. 響應式視頻代碼示例
<video width="640" height="480" controls autoplay preload="auto" loop
poster="myVideoPoster.jpg">
<source src="video/myVideo.ogv" type="video/ogg">
<source src="video/myVideo.mp4" type="video/mp4">
responsive video
</video>

如何讓視頻響應呢?咱們須要追加 max-width:100%聲明:

video { max-width: 100%; height: auto; }

問題:若是視頻是被 iframe 內嵌又如何實現響應式呢?最簡單的辦法是使用一個名爲 FitVids 的 jQuery 小插件。代碼以下:

清單 8. Iframe 引入的視頻實現響應式代碼示例
<script src="js/fitvids.js"></script>

<script>
$(document).ready(function(){
$("#content").fitVids();
});
</script>


響應式表格

實現數據表格響應的方式有不少種,要根據表格內容,數據量來進行具體的設計。流體表格並不等於響應式表格,好比一個百分比寬度表格,在小屏幕設備上能夠正常顯示但內容總體被壓縮得較小,可讀性差,並不表明它是真正響應的。

舉例說明,針對如下這個數據較多的表格,有多種設計思路能夠採用。

圖 10. 如何實現一個響應式的複雜表格之表格示例

如何實現一個響應式的複雜表格之表格示例

思路1:爲小屏幕隱藏沒必要要的列,精簡表格。主要利用 CSS table td:nth-child(n){display:none}實現。

思路 2:將橫向的表頭利用 CSS 改成縱向顯示並固定位置,其他內容部分不變並出現橫向滾動條。tbody 上應用 white-space:nowrap; tbody tr 下應用 display:inline-block;

思路 3:將每一行數據對應表頭顯示在一塊區域內,接下來每行依次類推。利用 HTML data 屬性,將表頭名稱寫到 CSS 中,td:before{content:attr(data-title);

思路 4:將純文本的表格在小屏幕上的餅圖或柱狀圖,以一種更豐富的形式顯示數據,前提是這是合適表格內容的。

思路 5:用一張小縮略圖顯示在小屏幕上並提示用戶點擊查看錶格,從而新開頁面以得到更大的屏幕空間顯示整個表格。

以上解決方案具體實現代碼請參考「參考資源」連接。


響應式設計推薦框架

使用 Modernizr 讓老版本 IE 支持 HTML5 元素,BootStrap, Semantic UI, Foundation 前端界面開發框架均可選擇。


總結

本文簡單介紹了經常使用的響應式設計工具,思路和技巧,除了須要掌握必定的技術實現手段,更須要有如何設計,如何佈局的思考,也不能忽略對高分辨率設備的支持,瞭解漸進加強與優雅降級的本質區別,真正實現頁面好看、好用、合理。

相關文章
相關標籤/搜索