響應式是指根據不一樣設備瀏覽器分辨率或尺寸來展現不一樣頁面結構、行爲、表現的設計方式。這裏總結了響應式網站設計須要涉及到的相關的內容,有不正確的歡迎你們指正。談到響應式網站,目前比較主流的作法是經過前端經過判斷userAgent來作頁面的302跳轉。javascript
那麼問題來了,使用userAgent的問題:css
固然咱們也都知道像bootstrap這種ui框架也是響應式的,即寫一份代碼,在瀏覽器和移動端都能跑,然而事實上這些事遠遠不夠的,並且在移動端爲何要加載那麼多PC端的內容?html
咱們理解的是完整的響應式頁面的設計不只僅是經過屏幕尺寸來動態改變頁面容器的寬度等,其實大部分人一般理解的都停留在這個方面。完整的響應式網站的實現其實須要考慮到如下這些問題:響應式佈局、響應式html和css、響應式媒體、響應式javascript。前端
先看幾個線上的樣例:java
http://ke.qq.com/huodong/shengkao/index.htmlnode
http://ke.qq.com/huodong/yikao2016/index.htmljquery
http://ke.qq.com/huodong/nianzhongppt/index.htmlgit
這些頁面在移動端和PC端使用同一個頁面(你們能夠用chrome瀏覽器一下),這樣就避免了多餘的302跳轉,另外頁面佈局、邏輯、圖片等內容都經過不一樣瀏覽器來適應。下面具體講下各個部分的實現所涉及的內容。github
響應式佈局是用來兼容瀏覽器分辨率,清晰度,橫屏,豎屏的頁面元素佈局方式。通常使用柵格方式實現。時間思路有兩種,一種是PC端優先,另外一種是以移動優先,PC端做爲一個擴展。因爲移動端的資源比較優先,通常比較推薦從移動端擴展到PC端,這樣就避免了在移動端加載多餘的PC端內容。響應式佈局主要能夠結合幾種實現方式:web
1,移動端佈局控制
使用 viewport標籤在手機瀏覽器上控制佈局控制不縮放等通用定義。
<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1" /> <meta name="apple-mobile-web-app-status-bar-style" content="blank" />
因爲這些定義在移動端必須定義,這裏仍是須要定義,用到PC端也不影響,只是有些多餘。
2,普通元素的柵格佈局
對於普通的div佈局,使用了通用簡單的柵格佈局,相信這個你們都知道原理:
.row{ width: 100%; } .row .col-1 { width: 8.33333333333% } .row .col-2 { width: 16.6666666667% } /* ...比較多,這裏省略 */ .row .col-12 { width: 100% }
這裏借鑑了其它的一下柵格系統的設計: Responsive Grid System Fluid 960 Grid(adaptjs) Simple Grid
3,不一樣設備元素容器佈局
通用柵格佈局並不能解決咱們所有的問題,例如某個頁面板塊列表,PC端一排展現4個,移動端一排展現2兩個,使用柵格的話咱們就須要從新定義.col-3和.col-6了。對於這種狀況咱們的處理方法也比較簡單,對於移動端瀏覽器,經過簡單的js邏輯判斷,在html的body中加入mobile的內容,在body裏面的相同元素使用不一樣的寬度佈局的方式。這種方式訂製化堅強,若是寬度佈局用的很少,便可以使用這種不一樣寬度佈局的方式來實現。這樣就實現了一個普通div在移動端和PC端的不一樣佈局。
.container{ width: 25%; } .mobile .container{ width: 50%; }
這兩個結合起來介紹是由於這兩個比較強相關。因爲移動端頁面的html可能相對簡單,可是擴展到PC會增長額外的html結構,例以下面截圖中的框中部分,在移動端時不顯示或顯示另外一種樣式,例以下面兩圖對比。那咱們如何作到兩個平臺兩種不一樣展現呢?
方法思路一:使用相同html結構,對於要在移動端要隱藏的dom元素,能夠經過display: none來控制html是否顯示;對於展現樣式不一樣的,須要在PC端額外引入css覆蓋移動端的原有樣式(以前說過了,PC端資源相對移動端比較充裕,PC端能夠接受額外增減小量的css文件來實現響應式)。
方法思路二:動態使用js渲染不一樣內容,可是這樣會增長移動端js大小,並且css樣式文件必不可少。相比之下,咱們使用了思路一的方案。其實使用js的渲染方案也是能夠的,不過畢竟保留html比使用js簡單。
講到這裏相信你們也都懂了。
響應式網站設計比較複雜的就是圖片媒體處理了。佈局作了響應式處理,可是在咱們手機訪問時,請求的圖片仍是PC瀏覽器上請求的大圖;文件體積大,消耗流量多,請求延時長。響應式媒體要解決的兩個關鍵點是媒體尺寸自適應和屏幕分辨率自適應。固然這裏使用到的媒體主要指圖片,但要明白的是,不只僅只有圖片。
先看看通常的媒體大小自適應解決方案,咱們沒有使用這裏的方案,而是結合借鑑了這裏的思路,並且咱們也有必要了解這些解決方案。
1,使用css背景圖片 (依賴media query)
將圖片設計爲背景圖片,並在css經過media query來加載所須要的背景圖片。這樣就會根據訪問設備的屬性來加載形影的圖片。可是沒法定義頁面圖片圖片屬性。
2,picture element (依賴瀏覽器新特性+midea query)
W3C已經有一個用於響應式圖形的草案:新定義標籤<picture>,但由於它還只是草案,目前尚未支持的瀏覽器,期待在不久的將來咱們能用上。雖然目前不支持,但咱們仍是來了解下這個瀏覽器的新特性,也和咱們一向的研究方向一致。 <picture>是一個圖形元素,內容由多個源圖組成,並由CSS Media Queries來適配出合理圖形,代碼規範以下
<picture width="500" height="500"> <source media="(min-width: 640px)" srcset="large-1.jpg 1x, large-2.jpg 2x"> <source media="(min-width: 320px)" srcset="med-1.jpg 1x, med-2.jpg 2x"> <source srcset="small-1.jpg 1x, small-2.jpg 2x"> <img src="small-1.jpg" alt=""> <p>Accessible text</p> <!-- Fallback content--> <noscript> <img src="external/imgs/small.jpg" alt="Team photo"> </noscript> </picture>
source: 一個圖片源; media: 媒體查詢,用於適配屏幕尺寸; srcset: 圖片連接,1x適應普通屏,2x適應高清屏; <noscript/>: 當瀏覽器不支持腳本時的一個替代方案; <img/>: 初始圖片;另外還有一個無障礙文本,相似<img/>的alt屬性。 <picture>目前還不支持,但它的原理咱們是可借鑑的,因此就誕生了一個用於圖片響應式處理的類庫picturefill
3,picturefill (依賴js+media query)
https://github.com/scottjehl/picturefill http://scottjehl.github.io/picturefill/
能夠認爲是picture元素的一個polyfill,(什麼是polyfill?晶哥第一次沙龍講過,就是修復瀏覽器特性不支持的"膩子")。 將來咱們可能使用picture元素來進行圖片在頁面的適應。而picturefill是w3c提供的最新的針對響應式圖片的設計方案,可是須要瀏覽器支持picture屬性,原理就是JS獲取Source的源以及CSS Media Queries規則,輸出適應圖片。
這個是picturefill實現的部分源碼,大體看了一下,原理就是使用javascript來解析picture元素定義的標籤,來在頁面上強行使用picture相似元素。可是我的以爲性能方面值得去考慮。
4,adaptive-images
實現原理是瀏覽器訪問服務器圖片時帶上瀏覽器的窗口信息,服務器獲取後根據窗口信息獲取相對應的圖片返回。 這是一個服務端解決方案,優勢:一是不用更改現有的HTML標籤結構,所以可快捷地應用於過去的項目;二是對於任何圖片,包括JS添加的,都會起做用,即圖片寬度不會大於瀏覽器寬度,三是因爲其採用服務端解決方案,兼容性很廣。 可是,其缺點也是明顯的:首先,其依賴Cookie和JS,瀏覽器信息須要經過js存放cookie,發送時放在頭部發送,這致使一些禁用或不能使用Cookie和JS的瀏覽器不能使用。而後是其對全部圖片都起做用,這不適用於那些須要加載大圖片的情形;最後,不適用於CDN,由於圖片都是針對特定設備即時生成的,我以爲能夠修改後端代碼作
5,responsive-images.js(依賴js)
官網:https://github.com/kvendrik/responsive-images.js 這個與picturefill相似,不過它不依賴media query,而是經過JS檢測瀏覽器的可見視口寬度來決定選擇合適的圖片,所以其兼容性很廣,全部的主流瀏覽器。同時也不須要額外的標籤,而是須要額外的屬性,可是它不支持JS添加的圖片,至少目前還不支持。
<img alt='kitten!' data-src-base='demo/images/' data-src='<480:smallest.jpg, <768:small.jpg,<960:medium.jpg,>960:big.jpg' />
6,不一樣屏幕分辨率自適應方案
主要是解決高清屏(retina屏)的問題,因爲高清屏與普通屏幕有所區別:
因爲高清屏的特性,1px是由2×2個像素點來渲染,那麼咱們樣式上的border:1px在Retina屏下會渲染成2px的邊框,與設計稿有出入,爲了追求1px精準還原,咱們就不得不拿出一個完美的解決方案。(此處沒去深究)JS檢測是否高清屏:var retina = window.devicePixelRatio > 1; 例如一個邊框的
@media only screen and (-webkit-min-device-pixel-ratio:2), only screen and (min-device-pixel-ratio:2) { button { border:none; padding:0 16px; background-size: 50% 50%; }
結合實現思路: 然而這裏沒有一種單一方案能知足咱們的需求,不過借鑑這些思路的處理過程,咱們的處理思路也基本相似:因爲這裏的圖片數據是異步拉取渲染的,並且咱們的圖片加載選擇和屏幕寬度無關,和瀏覽器設備相關,那就能夠經過瀏覽器經過js(或css)獲取用戶設備類型、分辨率,而後經過判斷用戶設備輸出適應的大小圖片圖片的dom結構,另外若是用戶屏幕是高清屏,還的輸出雙倍分辨率的圖片適應屏幕。
真正的響應式設計的網站,處理使用不一樣的佈局、html、css和圖片,還須要根據瀏覽器環境來異步加載不一樣的js文件。和以前思路同樣,這裏咱們主要經過設備環境判斷來異步加載不一樣的javascript,下面這樣就實現了安裝瀏覽器環境來加載了
if(isMobile){ require.async(['zepto', './mobileMain'], function($, main){ main.init(); }); }else{ require.async(['jquery', './main'], function($, main){ main.init(); }); }
這樣就有效保證了當時移動端時加載移動端須要的js同時避免了多餘的js文件的下載。至於這裏如何打包,就是另外一個問題了,並且有點坑要填,這裏開始咱們沒有處理好判斷邏輯打包的問題,後來經過本身開發構建插件實現這個邏輯的打包。
這裏實際不是咱們的實現部分,並且不符合咱們的需求,後臺部署實現也複雜,可是這裏仍是總結補充梳理一下來作完整地作個總結。
(1) 簡單網站的響應式結構
使用media query指定屏幕適應屬性實現網頁自適應,不一樣設備下的css寫在一個文件內,css按模塊管理。模塊分開,易於管理和編碼實現,也便於維護,是中小型網站實現響應式的不二選擇。
缺點:對於樣式複雜的網站沒有拆分,不能根據對應屏幕加載對應樣式,形成帶寬浪費;不利於優化和cdn。
(2) 分流響應式站點
javascript根據userAgent特性來加載不一樣域下的css,能夠儘量避免使用media query,不一樣瀏覽器環境下的樣式分離管理,實現了平臺樣式分離,易於cdn管理。
缺點:須要維護多套樣式表,即便公共部分抽離,一旦修改,影響多個平臺環境;須要判斷UA;架構實現稍微複雜。
(3) 後臺頁面直出
和adaptive-images實現方法相似,首先是創建在不一樣環境下樣式分離管理的基礎上,後臺根據靜態文件請求所帶的cookie信息直出靜態頁面,拉取相對應的css。
缺點:須要依賴cookie機制,服務器須要進行處理。(不過這層直出可使用node中間服務獲取,由這層服務請求後臺,再返回給前端)
再來回頭看下本文總結了啥,仍是回到開頭的幾個問題,響應式網站設計實現包含的幾個方面:響應式佈局、響應式html和css、響應式媒體、響應式javascript,總結了較多別人的實現方案,也提出了咱們的實踐方法,另外補充了下通用的響應式架構。 就先總結到這裏,另外,有不許確的歡迎拍磚,以爲還行的也歡迎點贊哦~哈哈
原文連接(更多相關文章):http://ouvens.github.io/frontend-css/2016/01/15/responsive-css.html