跨終端/響應式頁面不外乎是讓各種分辨率的屏幕都能順利閱讀你的頁面,常規來講一個跨終端頁面,在寬屏的電腦上看和在小屏幕手機上看的布局是不同的,布局不同的原因是為了讓讀者更好地閱讀你的頁面,見下圖:
這里有點要提到的是,我們常規會將PC版的頁面和移動端設備的頁面獨立開來設計,這樣會讓PC端的頁面布局更靈活和好維護。如果你希望你的頁面能適配包括PC端在內的任何設備,那么下面幾個小工具可以方便你顧及舊版本IE所存在的困擾:
⑴ IE8-不能識別HTML5的<hearder>、<article>、<footer>、<figure>等標簽,可以通過 html5.js 來解決:
<!--[if lt IE 9]> <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> <![endif]-->
然后將下面代碼寫入你的base.css來格式化html5標簽:
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; }
⑵ IE8-不支持CSS3 media queries,即不支持"@media only screen"語法,可以通過 css3-mediaqueries.js 來解決:
<!--[if lt IE 9]> <script src="http://css3-mediaqueries-js.googlecode.com/svn/trunk/css3-mediaqueries.js"></script> <![endif]-->
本文僅談論移動端的頁面適配方式,不考慮PC屏幕環境,不過原理均是相通的。本文也不討論SPA/OPA的實現。
(一)百分比賦值
相信許多剛接觸響應式頁面設計的朋友,第一時間考慮到的就是將layout數值設為百分值形式,包括width、height、padding、margin等大小、偏移、方位的賦值。 例如:

<!doctype html> <html> <head> <style> html, body { magin: 0; padding: 0; } .outDiv { margin: 3% auto; width: 85%; height: 350px; background: red; } </style> <meta charset="utf-8"> <title>test</title> </head> <body> <div class="outDiv"> Hello </div> </body> </html>
常規來說我們會用固定值或者自動值來設置容器的高度,一旦我們想要使用百分比來設置元素高度時,我們可能會這么寫:

<!doctype html> <html> <head> <style> html, body { magin: 0; padding: 0; } .outDiv { margin: 0 auto; width: 85%; height: 50%; background: red; } </style> <meta charset="utf-8"> <title>test</title> </head> <body> <div class="outDiv"> Hello </div> </body> </html>
但在運行代碼后,你會發現該高度樣式并沒有生效。解決這個問題的方法很簡單,給外層元素"bady,html"添加一個 height:100% 的樣式即可,具體原理可以查閱我的舊文章CSS百分比定義高度的冷知識 。
VIEWPORT介紹
這里先打斷一下文章,簡單介紹下“viewport”,做移動端頁面開發的朋友必須了解viewport。
我們在使用移動端設備瀏覽網頁時,移動端瀏覽器是直接把整個頁面放到一個虛擬的視圖里來顯示的,通常來說這個虛擬的視圖大小會比手機屏幕大,用戶可以通過手勢操作來平移、縮放這個視圖。
為了方便理解,我們假設有這么一個頁面:
① 如果沒有viewport這種東西,在移動端瀏覽器上訪問該頁面可能是這樣的:
② 有了viewport后是這樣的:
viewport誕生的初衷是為了讓移動端更人性化地瀏覽PC端頁面,但它也帶來了一些問題,從而催生了類似iscroll.js的工具。
想了解更多關于viewport的知識請點這里。
(二)禁用移動端設備的部分特性(非必要,按需使用)
⑴ 禁用viewport縮放功能
在頁面頭部加上如下語句來禁用viewport的縮放特性(響應式頁面基本是按百分比來布局和適配的,用戶縮放頁面反而影響閱讀效果):
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
如上我們設置viewport初始化時便適配設備瀏覽器的寬度,且無法縮放,該meta標簽具體參數如下:
width:viewport 的寬度,可以指定一個固定值,如650;或者可以是device-width,表示設備的寬度。
height:和 width 相對應,可指定高度。
initial-scale:頁面初始縮放比例(0-1)
maximum-scale:允許用戶縮放到的最大比例(0-1)
minimum-scale:允許用戶縮放到的最小比例(0-1)
user-scalable:用戶是否可以手動縮放(yes/no)
上述meta標簽可能會在舊版的iphone中導致布局錯誤的問題,因為舊版的iphone會默認把頁面做980寬度渲染,但最終以320寬度顯示,我們可以再接著加一句meta標簽來兼容(讓iphone以320的寬度來渲染頁面):
<meta name="MobileOptimized" content="320">
⑵ 禁用Webkit文本調節功能
無論是移動端還是PC端,webkit內核的瀏覽器會自動調節文字大小。例如Chrome不會顯示小于12px的字號效果,即使你設置 font-size:10px,頁面也將渲染為12px的大小。
另外移動設備在縱向模式和橫向模式查閱頁面時,文本的大小也會被瀏覽器調節:
禁用該功能的途徑是使用-webkit-text-size-adjust 來設置(chrome28+已失效):
body { -webkit-text-size-adjust: 100%; }
(三)CSS3 media queries
CSS3 media queries(后簡稱為CMQ)算是響應式頁面設計的一把瑞士軍刀,可以把你的頁面在不同分辨率的環境下雕琢成對應的、最好看的輪廓,掌握了CMQ也算是掌握了響應式頁面設計的基礎。
CMQ在樣式文件中的使用很簡單,其語法為
@media only screen and (max/min-width/height: 960px) {
/* 樣式定義 */
}
其中橙色高亮的 “only screen” 參數表示限定當訪問環境(媒體類型)為彩色屏幕設備時才生效。
該參數可選值為 all
|
aural
|
braille
|
handheld
|
print
|
projection
|
screen
|
tty
|
tv
|
embossed
除非該參數數值為all,否則可以在前面加個only限定類型。對于移動端和PC端,我們只需設為 "screen" 或 "only screen" 即可,建議使用后者,其語義更為嚴謹。
另一個高亮的參數 “max/min - width/height” 表示當屏幕的寬度/高度超過或者小于某個值時則生效,具體可以看下面的示例:
⑴ Max Width
@media only screen and (max-width:500px){ .outDiv { margin: 0 auto; width: 85%; height: 50%; background: red; } }
該代碼段表示只有當屏幕寬度小于500px時才生效。
⑵ Min Width
@media only screen and (min-width:500px){ .outDiv { margin: 0 auto; width: 85%; height: 50%; background: red; } }
該代碼段表示只有當屏幕寬度大于500px時才生效。
⑶ Max/Min Height
同 max/min-width ,表示當屏幕高度小于/大于設定值時樣式才生效。常規來說,我們使用 max/min-width 比較多,而很少使用 max/min-height 。
⑷ Multiple Media Queries
有時候我們需要定義樣式是在某個分辨率區間(比如500px-900px)才生效,這時候我們可以疊加使用 max/min-width/height 。
方法很簡單,加多一個“and”即可:
@media only screen and (mix-width:500px) and (max-width:900px){ .outDiv { margin: 0 auto; width: 85%; height: 50%; background: red; } }
⑸ Device Width
我們上述的 max/min-width/height 均是針對可視區域分辨率的,如果希望針對設備的實際寬度來適配,我們可以利用 max-device-width 來實現:
@media only screen and (max-device-width:900px){ .outDiv { margin: 0 auto; width: 85%; height: 50%; background: red; } }
該代碼段表示當設備屏幕寬度小于900px時,其內部定義的樣式生效。打個比方,如果瀏覽器打開了一個小窗口(非全屏顯示),該窗口的寬度對該段代碼沒有任何影響。
只要你的電腦屏幕寬度是大于900px的(你應該不會使用分辨率太低的PC屏幕吧?),上面這段代碼就不會生效。
⑹ 標簽化的CMQ
CMQ不僅僅可以寫在樣式文件中,也可以標簽化,直接寫在頁面<head>標簽內,其寫法如下:
<link rel="stylesheet" media="only screen and (max-width: 800px)" href="small_screen.css" />
該代碼表示在視圖寬度小于800px時則引入small_screen.css這個外部樣式文件。
另外你還可以利用orientation來判斷設備的方向(垂直模式portrait/橫向模式landscape):
<link rel="stylesheet" media="all and (orientation:portrait)" href="portrait.css"> <link rel="stylesheet" media="all and (orientation:landscape)" href="landscape.css">
但常規我們并不推薦使用orientation,因為它無法告知你關于設備分辨率的任何信息,所以作為一個通用的規則,應該避免orientation
而使用device-width
代替。
(四)例子
我們來做一個小例子,讓它能按下圖要求,在三個分辨率區間做不同的適配布局:
先寫原型框架:

<!doctype html> <html> <head> <style> html, body { magin: 0;padding: 0;height:100%; font-size:1.2em;} .wrap{ margin:2% auto 0 auto; width:95%;} header { width:100%; height:5%;background-color:#FF9673;} nav{ float:left;width:20%; min-height:600px;background-color:#FF9673;} article{ background-color:#FFD24D;} aside{ background-color:#73B9FF;} </style> <meta charset="utf-8"> <title>Demo</title> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" /> </head> <body> <header>top-banner</header> <div class="wrap"> <nav></nav> <article> <p>the main area</p> </article> <aside>sth</aside> </div> </body> </html>
接著利用CMQ,依照三種分別率區間來定義樣式:

<!doctype html> <html> <head> <style> html, body { magin: 0;padding: 0;height:100%; font-size:1.2em;} .wrap{ margin:2% auto 0 auto; width:95%;} header { width:100%; height:5%;background-color:#FF9673;} nav{ float:left;width:20%; min-height:600px;background-color:#FF9673;} article{ background-color:#FFD24D;} aside{ background-color:#73B9FF;} @media only screen and (min-width:1000px){ nav{display:none;} article{ float:left; margin-right:2%; width:70%; min-height:600px;} aside{ float:left; width:28%; min-height:600px;} } @media only screen and (min-width:601px) and (max-width:999px){ header{display:none;} article{ float:left; margin-left:2%; width:78%; min-height:600px;} aside{ display:none;} } @media only screen and (max-width:600px){ nav{display:none;} article{ width:100%; min-height:600px;} aside{ display:none;} } </style> <meta charset="utf-8"> <title>Demo</title> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" /> </head> <body> <header>top-banner</header> <div class="wrap"> <nav></nav> <article> <p>the main area</p> </article> <aside>sth</aside> </div> </body> </html>
這里需要提醒的一點是,我們對于文本字體大小的定義建議使用 em 來賦值,畢竟不同終端不同瀏覽器會依據分辨率大小來設定文本的缺省大小,從而方便用戶閱讀,利用 em 來按比例調整字體大小能迎合終端瀏覽器的這個人性化特點。
共勉~
文章列表