響應(yīng)式網(wǎng)頁(yè)布局的實(shí)現(xiàn)方法原理
交互設(shè)計(jì)師,要滿(mǎn)足各自不通分辨率和設(shè)備的頁(yè)面布局展現(xiàn)方式。而視覺(jué)設(shè)計(jì)師,則要考慮到頁(yè)面性能和移動(dòng)端帶寬問(wèn)題,權(quán)衡下頁(yè)面的酷炫效果和視覺(jué)色彩的運(yùn)用。而前端和后臺(tái)開(kāi)發(fā)工程師,則要完成滿(mǎn)足視覺(jué)需求和交互功能,更要考慮到頁(yè)面加載性能和消耗帶寬問(wèn)題,更重要的是移動(dòng)端安全性能方面!既然響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)牽涉到了這么多的方方面面,那我們又該如何去實(shí)現(xiàn)這種頁(yè)面呢?對(duì)此我也特意收集了一些響應(yīng)式網(wǎng)頁(yè)的實(shí)現(xiàn)方法原理
首先我們應(yīng)該遵循移動(dòng)優(yōu)先原則,交互和設(shè)計(jì)應(yīng)以移動(dòng)端為主,PC則作為移動(dòng)端的一個(gè)擴(kuò)展;一個(gè)頁(yè)面需要兼容不同終端,那么有兩個(gè)關(guān)鍵點(diǎn)是我們需要去做到響應(yīng)式的:響應(yīng)式布局和響應(yīng)式內(nèi)容(圖片、多媒體)。
一、響應(yīng)式布局
如我們需要兼容不同屏幕分辨率、清晰度以及屏幕定向方式豎屏(portrait)、橫屏(landscape),怎樣才能做到讓一種設(shè)計(jì)方案滿(mǎn)足所有情況?對(duì)此,馬海祥覺(jué)的我們的布局應(yīng)該是一種彈性的柵格布局,不同尺寸下彈性適應(yīng),如以下頁(yè)面中各模塊在不同尺寸下的位置:
那么我們具體要怎么做呢?
1、Meta標(biāo)簽定義
使用 viewport meta 標(biāo)簽在手機(jī)瀏覽器上控制布局
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1" />
通過(guò)快捷方式打開(kāi)時(shí)全屏顯示
<meta name="apple-mobile-web-app-capable" content="yes" />
隱藏狀態(tài)欄
<meta name="apple-mobile-web-app-status-bar-style" content="blank" />
iPhone會(huì)將看起來(lái)像電話(huà)號(hào)碼的數(shù)字添加電話(huà)連接,應(yīng)當(dāng)關(guān)閉
<meta name="format-detection" content="telephone=no" />
2、使用Media Queries適配對(duì)應(yīng)樣式
常用于布局的CSS Media Queries有以下幾種:
設(shè)備類(lèi)型(media type):
all所有設(shè)備;
screen 電腦顯示器;
print打印用紙或打印預(yù)覽視圖;
handheld便攜設(shè)備;
tv電視機(jī)類(lèi)型的設(shè)備;
speech語(yǔ)意和音頻盒成器;
braille盲人用點(diǎn)字法觸覺(jué)回饋設(shè)備;
embossed盲文打印機(jī);
projection各種投影設(shè)備;
tty使用固定密度字母柵格的媒介,比如電傳打字機(jī)和終端。
設(shè)備特性(media feature):
width瀏覽器寬度;
height瀏覽器高度;
device-width設(shè)備屏幕分辨率的寬度值;
device-height設(shè)備屏幕分辨率的高度值;
orientation瀏覽器窗口的方向縱向還是橫向,當(dāng)窗口的高度值大于等于寬度時(shí)該特性值為portrait,否則為landscape;
aspect-ratio比例值,瀏覽器的縱橫比;
device-aspect-ratio比例值,屏幕的縱橫比。
例子:
/* for 240 px width screen */
@media only screen and (max-device-width:240px){
selector{ ... }
}
/* for 320px width screen */
@media only screen and (min-device-width:241px) and (max-device-width:320px){
selector{ ... }
}
/* for 480 px width screen */
@media only screen (min-device-width:321px)and (max-device-width:480px){
selector{ ... }
}
適用于布局的Media Queries,這里在馬海祥博客上我們就不再做詳述,有興趣的話(huà),可通過(guò)官方文檔進(jìn)一步了解。
3、表格(table)的響應(yīng)式處理
那么對(duì)于表格(table)的響應(yīng)式處理該是怎樣的呢?我們?cè)撊绾瓮黄芓able的局限性呢?接下來(lái)我們來(lái)了解以下的幾種針對(duì)表格響應(yīng)式處理的方法:
(1)、隱藏不重要數(shù)據(jù)列
處理前:
處理后:
實(shí)現(xiàn)方法代碼:
@media only screen and (max-width: 800px) {
table td:nth-child(2),
table th:nth-child(2) {display: none;}
}
@media only screen and (max-width: 640px) {
table td:nth-child(4),
table th:nth-child(4),
table td:nth-child(7),
table th:nth-child(7),
table td:nth-child(8),
th:nth-child(8){display: none;}
}
以用戶(hù)角度思考,每個(gè)人對(duì)數(shù)據(jù)的認(rèn)知不同,或許你隱藏的數(shù)據(jù)對(duì)于他卻是很重要的,所以對(duì)于這種方法馬海祥并不推薦。
(2)、多列橫向變2列縱向
處理前:
處理后:
實(shí)現(xiàn)方法:<thead>定位隱藏,<td>變塊元素,并綁定對(duì)應(yīng)<th>列名,然后用偽元素的content:attr(data-th)實(shí)現(xiàn)<th>:
(3)、固定首列,剩余列橫向滾動(dòng)
處理前:
處理后:
實(shí)現(xiàn)原理代碼:
thead {float:left;}
tbody {display:block;width:auto;overflow-x:auto;}
二、響應(yīng)式內(nèi)容
1、響應(yīng)式圖片
帶寬是手機(jī)終端的硬傷,如果我們只是頁(yè)面布局做了響應(yīng)式處理,在我們用手機(jī)訪(fǎng)問(wèn)時(shí),請(qǐng)求的圖片還是PC上的大圖;文件體積大,消耗流量多,請(qǐng)求延時(shí)長(zhǎng),因此導(dǎo)致的問(wèn)題也是不可估量的。那么我們就得把圖片也處理成響應(yīng)式的根據(jù)終端類(lèi)型尺寸分辨率來(lái)適配出合理的圖形。
處理原理:瀏覽器獲取用戶(hù)終端的屏幕尺寸、分辨率邏輯處理后輸出適應(yīng)的圖片,如屏幕分辨率320*480,那么我們匹配給它的是寬度應(yīng)小于320px的圖片。如果終端屏幕的DPI(device pixels)DPI詳解值很高,也就是高清屏,那么我們就得輸出2倍分辨率的圖形(寬:640px);以保證在高清屏下圖形的清晰度。各種移動(dòng)終端的屏幕參數(shù)可通過(guò)http://screensiz.es/phone查詢(xún)。
解決方案:其實(shí)W3C已經(jīng)有一個(gè)用于響應(yīng)式圖形的草案:新定義標(biāo)簽<picture>,因?yàn)樗€只是草案,目前還沒(méi)有支持的瀏覽器,期待在不久的未來(lái)我們能用上。雖然目前不支持,但我們還是來(lái)了解下,為之后的內(nèi)容做個(gè)鋪墊。
<picture>是一個(gè)圖形element,內(nèi)容由多個(gè)源圖組成,并由CSS Media Queries來(lái)適配出合理圖形,代碼規(guī)范如下:
- <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: 一個(gè)圖片源;
media: 媒體查詢(xún),用于適配屏幕尺寸;
srcset: 圖片鏈接,1x適應(yīng)普通屏,2x適應(yīng)高清屏;
<noscript/>: 當(dāng)瀏覽器不支持腳本時(shí)的一個(gè)替代方案;
<img/>: 初始圖片;另外還有一個(gè)無(wú)障礙文本,類(lèi)似<img/>的alt屬性。
雖然<picture>目前還不支持,但它的原理我們是可借鑒的,所以就誕生了一個(gè)用于圖片響應(yīng)式處理的類(lèi)庫(kù)Picturefill
- <span data-picture data-alt="圖片描述文本">
- <span data-src="small.jpg"></span>
- <span data-src="medium.jpg" data-media="(min-width: 400px)"></span>
- <span data-src="large.jpg" data-media="(min-width: 800px)"></span>
- <span data-src="extralarge.jpg" data-media="(min-width: 1000px)"></span>
- <!-- 瀏覽器不支持JS時(shí)的備用方案. -->
- <noscript>
- <img src="external/imgs/small.jpg" alt="圖片描述文本">
- </noscript>
- </span>
其原理就是JS獲取Source的源以及CSS Media Queries規(guī)則,輸出適應(yīng)圖片,邏輯細(xì)節(jié)這里不再解析,感興趣的可查看其JS代碼,邏輯不是很復(fù)雜,也可以自己封裝一個(gè)類(lèi)庫(kù),以適用于自身產(chǎn)品,例如圖片加載失敗的替代方案。
當(dāng)然,在未來(lái)的CSS Image Level 4中已經(jīng)實(shí)現(xiàn)了響應(yīng)式圖片的原生語(yǔ)法:image-set
<image-set> = image-set([ <image-set-decl>, ]* [ <image-set-decl> | <color>])
<image-set-decl> = [ <image> | <string> ] <resolution>
那么我們的響應(yīng)式圖片可以這樣重寫(xiě)了
background-image:url(default.jpg); /* 普通幕 */
background-image: -webkit-image-set(url(medium.jpg) 1x, url(large.jpg) 2x); /* Retina高清屏 */
注:Webkit 目前只實(shí)現(xiàn)了 url() 形式的取值,且dppx值取負(fù)值[-2x]貌似也是合法的。
當(dāng)然除此之外,還有其他的響應(yīng)式處理,如服務(wù)端user-agent嗅探。
2、高分辨率(DPI)下的響應(yīng)式處理
(1)、SVG:優(yōu)點(diǎn)可承載色彩豐富、設(shè)計(jì)復(fù)雜圖形,且渲染不會(huì)出現(xiàn)邊緣不順滑;缺點(diǎn)是IE的支持不完美。
(2)、Icon fonts:支持多瀏覽器,圖形顏色大小的修改成本低,易于維護(hù);圖形表現(xiàn)單一,不支持色彩豐富且復(fù)雜的圖形,IE6渲染有毛邊。
(3)、-webkit-image-set:只支持單個(gè)圖形的適配,不利于圖形合并,兼容不完美(Safari 6+, Chrome 21+)。
JS檢測(cè):var retina = window.devicePixelRatio > 1;
- CSS Media Query:
- @media (-webkit-min-device-pixel-ratio: 2), /* Webkit-based browsers */
- (min--moz-device-pixel-ratio: 2), /* Older Firefox browsers (prior to Firefox 16) */
- (min-resolution: 2dppx), /* The standard way */
- (min-resolution: 192dpi) /* dppx fallback */
3、高分辨率下的1px border
由于高清屏的特性,1px是由2×2個(gè)像素點(diǎn)來(lái)渲染,那么我們樣式上的border:1px在Retina屏下會(huì)渲染成2px的邊框,與設(shè)計(jì)稿有出入,為了追求1px精準(zhǔn)還原,我們就不得不拿出一個(gè)完美的解決方案。
在Photoshop中,如果需要看似0.5px的邊框,常見(jiàn)的方法就是對(duì)1px邊框加上陰影模糊1px。同理,我們?cè)趓etina屏下需要做到真實(shí)的1px邊框,可利用box-shadow屬性模擬。
- @media only screen and (-webkit-min-device-pixel-ratio:1.5),
- only screen and (min-device-pixel-ratio:1.5) {
- button {
- border:none;
- padding:0 16px;
- box-shadow: inset 0 0 1px #000,
- inset 0 1px 0 #75c2f8,
- 0 1px 1px -1px rgba(0, 0, 0, .5);
- }
- }
留給我們的思考
⊕響應(yīng)式不只是技術(shù)的實(shí)現(xiàn),它更像是一種對(duì)于設(shè)計(jì)的全新思維模式
⊕瀏覽的體驗(yàn)短期內(nèi)還無(wú)法超越原生應(yīng)用
⊕左手操作習(xí)慣的交互
⊕Webapp的消息推送
⊕調(diào)用本地文件系統(tǒng)的能力弱
⊕響應(yīng)式圖片的解決方案
⊕對(duì)PC事件的兼容
⊕WebAPP頁(yè)面體積的響應(yīng)式適配
⊕代碼實(shí)現(xiàn)和內(nèi)容可維護(hù)性之間的權(quán)衡
⊕控制設(shè)計(jì)開(kāi)發(fā)成本