關於響應式佈局,在以前的工做中已經接觸到一些,最近看了 Ben Frain的《響應式web設計》這本書大受啓發,趁閒下來的時候把我的對於移動端網頁前端開發的一些經驗總結一下。css
首先解釋一下響應式佈局的概念:html
響應式佈局是Ethan Marcotte在2010年5月份提出的一個概念,簡而言之,就是一個網站可以兼容多個終端——而不是爲每一個終端作一個特定的版本。這個概念是爲解決移動互聯網瀏覽而誕生的。前端
(摘自http://www.jiawin.com/response-type-layout-design/)android
在具體展開以前,我想先說一下非響應式佈局的手機網頁製做,以我如今手頭上的項目爲例。web
拿到這個項目的設計稿以後,個人想法是,它不是一個適於響應式佈局的項目,理由有2:第一,這個項目的PC端網站和手機端網站是分別開發的,手機端的網站沒必要同時適應電腦的大屏幕;第二,這個項目的設計使用了大量圖片,背景也是由一張大圖構成,與響應式佈局的簡潔風格相悖。基於以上兩點緣由,我並未採用響應式佈局,而是採用了按照設計稿中的640px像素寬度進行製做,在網頁<head>部分加上<meta name="viewport" id="viewportid" content="target-densitydpi=320,width=640,user-scalable=no">的方法,使網頁在手機上能滿屏顯示。瀏覽器
viewport是指移動設備瀏覽器的視區,手機瀏覽器是把頁面放在一個虛擬的「窗口」(viewport)中,一般這個虛擬的「窗口」(viewport)比屏幕寬,這樣就不用把每一個網頁擠到很小的窗口中(這樣會破壞沒有針對手機瀏覽器優化的網頁的佈局),用戶能夠經過平移和縮放來看網頁的不一樣部分。app
(摘自http://www.cnblogs.com/loalongblogs/archive/2011/06/21/2085971.html)
ide
因爲網頁是按照640px製做的,因此將viewport的寬度設置爲640。至於另一個屬性densitydpi,它是指屏幕每英寸顯示的像素點,這裏爲何要將其設置爲320呢?佈局
通常的lcd屏顯的densitydpi爲160.測試
若是想在電腦上顯示比較大的樣子,而在移動設備上令其剛好徹底顯示。
能夠這麼實現。
<meta name="viewport" content="target-densitydpi=320,width=640,user-scalable=no"/>
即,對於160densitydpi 的設備來講,將以320densitydpi來顯示。
那麼,若是設備寬分辨率爲320(android 手機廣泛這樣子),則將在320分辨率內顯示 320/160*320=640px的分辨率。
即,640px寬度 將在手機上 剛好所有寬度顯示。而640px寬度,對於laptop端,也是一個比較合適的分辨率。
(摘自http://zhan.renren.com/tag?value=webstatic)
這樣設置以後,用手機進行測試(Android),發現並不成功,網頁仍然溢出到屏幕以外了。通過諮詢,得知須要在頁面中加入一段js代碼:
if (window.innerWidth > 640) {
document.getElementById('viewportid').setAttribute('content', 'target-densitydpi=285,width=640,user-scalable=no');
}
原理?我還在研究...⊙﹏⊙b汗... 不過貌似這裏的285改爲別的數字也沒差?
這樣,網頁在手機上就能夠滿屏顯示了。這個方法的優勢是,不須要爲不一樣尺寸的手機考慮不一樣的樣式,它始終會滿屏顯示(至少測試的幾部手機都是如此),代碼比較簡單;缺點也很明顯,網頁缺乏對超過640px屏幕的支持,不夠靈活,並且對於更大的設備必須從新開發獨立的網站,成本更高。
在移動互聯網高速發展,各類移動設備不斷出現的今天,響應式佈局開始被提出,它是一種更爲靈活,可以適應各類終端的佈局。它的優缺點是:
(摘自http://www.jiawin.com/response-type-layout-design/)
響應式佈局的網頁應該如何製做呢?爲了方便講述,我以本身嘗試製做的一個網頁爲例。
這個網頁的佈局包括頭部<header>,在最頂部,其中包含logo和導航;
主體區域<div id="content">,包含了<div id="main">和<aside>兩部分,<aside>在右邊;
最後是頁腳<footer>。
首先爲頁面添加<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=2.0" />
width=device-width :自適應屏幕大小;initial-scale=1.0 :初始縮放是1倍;minimum-scale=1.0:最小容許縮放是1倍;maximum-scale=2.0 :最大容許縮放是2倍;
接着,我給<header>設置寬度爲100%,內部用一個div包裹logo和nav,這個div的寬度也設爲一個百分數並居中顯示,具體值是多少呢?按照書上的一個公式,用目標元素的寬度除以上下文元素的寬度,獲得的數字轉化爲百分數就是咱們須要的值。(注意,公式裏面的寬度是指設計稿中的實際像素值。)這裏,這個div的上下文元素是<header>,公式算出來的值大概是68%多(儘可能多保留一些小數,使結果更精確)。同理也能夠算出nav以及nav下面每一個元素的寬度。
那麼<header>的高度呢,也用百分數嗎?這裏我嘗試使用百分數但沒有做用,緣由是<header>的上下文元素<body>並無一個肯定的高度值(<body>的寬度默認是屏幕的寬度),並且咱們也不可能給body一個高度值,由於網頁在縱向上無限擴展的。再者,我也沒有爲<header>設置百分比高度的打算,由於我不但願logo和nav被等比例縮小,而但願它們保持比較清楚的大小,但也不是一成不變。這時候就涉及到響應式佈局中用em代替px的方法。
我在css中聲明body的font-size爲100%,這時1em=16px,用元素的像素值除以16就能夠獲得em值。使用em和px的區別在於,當咱們在media query媒介查詢裏面更改body的font-size值的百分比值的時候(好比改成90%),1em就再也不等於16px了。而等於16*0.9。
爲<header>的高度設置了em值以後,再爲logo和nav設置高度爲100%就能夠了。另外,爲了保持logo圖片的寬高比例協調,logo的寬度也不是百分比值,而是具體的em值,但這樣會出現一個問題:當瀏覽器窗口被縮小到必定程度的時候,logo和nav就被擠壓到了一塊兒,再縮小的話<header>下面的div就已經裝不下他們兩個了。這時我再次使用媒體查詢來進行判斷,當視口小於某個值的時候,將logo和nav的寬度都設爲100%,float值爲none,並居中顯示,這樣logo和nav就分爲兩行顯示了。簡略代碼以下:
@media screen and (max-width: 某個像素值){
/*css樣式*/
}
這樣,網頁頭部的響應式佈局就算基本完成了。接下來的<content>部分,正常狀況下#main和aside是分左右顯示的,當視口小於某個值的時候,我感受顯示效果過小了,這時候基本上來到了移動設備的一個寬度,因此我決定再也不將aside顯示在#main的右邊,而是放到它的下面去。
後面的工做大致雷同,就是要在視口不斷變小的過程當中,發現樣式中的不和諧現象,充分考慮用戶體驗,給予對應的css樣式。如#main中的列表,正常是三個一行顯示的,會根據視口大小逐步從3個到2個再到1個。
最後,關於響應式佈局再補充幾點:
1.彈性圖片:首先爲<img>元素設置max-width:100%,這樣全部的<img>圖片都會隨着視口的改變而按比例縮放且不會超過圖片自己的尺寸;
2.HTML5和CSS3:這兩個前沿技術是最適合於響應式佈局的,用它們編寫出的網頁代碼簡潔、易維護、高度語義化、對背景圖片和js腳本的依賴小,並且媒體查詢功能自己就出自CSS3;
3.使用字體圖標代替圖片圖標(http://icomoon.io/app/#/select):這樣作的好處是能減小http請求,加快頁面加載速度,並且圖標不易失真,改變大小和顏色也很方便(和字體同樣);
4.跨瀏覽器問題:使用一些js補丁來修復老舊瀏覽器對HTML5和CSS3的不支持,以及優雅降級。