隨着大屏手機越來越普及,在移動端H5頁面中,圖片像素的清晰度不夠高已經成為了影響體驗的重要因素。為了解決這一問題,設計師交付的設計稿也從640px變成了750px。那到了UI開發這個階段,在CSS編碼中如何還原視覺稿的真實寬高?如何在大屏手機上輸出高清晰度圖片?如何合理進行CSS布局,並保證多種屏幕終端體驗的一致性?
一、SVG圖標矢量化
假設我們已經拿到了一個針對iphone6的高清視覺稿 750×1334。首先把頁面中所有不能直接通過前端代碼實現的靜態資源(如圖片、特殊文字等)進行切圖處理,另外將icon圖標拼合成SVG Sprite。
SVG Sprite是什麼?有什麼優勢?
SVG Sprite作為一種可縮放的矢量圖形,比PNG sprite這種位圖清晰度要高很多,如下圖所示,更適合在大屏時代作為雪碧圖的輸出形式。
那SVG Sprite要怎麼生成?
這裡提供兩種方法,先說第一種IcoMoon。一般我們拿到的是PSD的設計稿,icon素材是用鋼筆工具和形狀工具畫出的矢量圖形。我們可以從PS中複製路徑拷貝到fireworks中,經過一系列操作就可以輸出SVG圖片了,再通過IcoMoon將fireworks導出的多個SVG 小圖拼合成SVG Sprite。具體方法參考張大神的《PSD小圖標變身SVG Sprites/font-face歷險記》。
經過一系列複雜的操作過程,SVG雪碧圖終於生成。是不是賊麻煩?
那最簡單的辦法莫過於安裝Photoshop CC 2015,一鍵導出SVG 雪碧圖。操作步驟:文件-導出-快速導出為SVG。
另外如下圖所示,建議SVG Sprite採用跟PNG Sprite一致的使用方法。
[class^="icon-"]{
background: url(../images/sprite.svg) no-repeat;
background-size: 1.00rem auto;
}
.icon-qq{
background-position: -0.30rem 0;
}
二、圖片高清化
圖片高清化是目前適配大屏手機亟待解決的一個問題。因為我們發現,通過640px的設計稿輸出@2x圖的方式,在iphone 6plus等大屏機型上效果已經不太理想。
1、背景圖片高清化
對背景圖高清化一般我們提供兩種方法,一種是Media Query,另一種是「image-set」。
(1)Media Query
媒體查詢的方法對開發者來說一般並不陌生,即對不同的設備像素比的顯示屏加載不同的圖片。最新的Photoshop CC 2015,支持在圖層面板中直接命名@1x@2x,一鍵生成需要的多種分辨率的圖片。媒體查詢方法如下:
/* 高清顯示屏(設備像素比例大於等於2)使用2倍圖 */@media only screen and (-webkit-min-device-pixel-ratio:2), only screen and ( min-device-pixel-ratio:2){ background-image: none;}/* 高清顯示屏(設備像素比例大於等於3)使用3倍圖 */@media only screen and (-webkit-min-device-pixel-ratio:3), only screen and ( min-device-pixel-ratio: 3){ background-image: none;}
(2)「image-set」
與媒體查詢不同的是,CSS Image Level 4 中實現了一種原生語法的「image-set」來選擇不同的圖片。
background-image: none;background-image: -webkit-image-set( url(image@1x.png) 1x, url(image@2x.png) 2x);}
對比Media Query和「image-set」,Jason Grigsby在他的《Safari 6 and Chrome 21 add image-set to support retina images》一文中寫到:Unlike a media query, image-set isn’t telling the browser what image to use, but instead provides options. In the future, I hope that someone using a high density device on a slow connection might be able to tell the browser that they only want low resolution images. 翻譯過來大概意思是:與Media Query不同的是,「image-set」並不是告訴瀏覽器使用哪張圖片,而是提供一種選擇。在未來,我希望用戶在低網速環境下使用高清設備的時候,瀏覽器可以自動識別並加載低分辨率圖片。
比較遺憾的一點是,「image-set」僅支持PC端chrome瀏覽器、移動端IOS8.1以上、android4.4以上,現在他僅是CSS4的一個草案,相信不遠的將來,「image-set」一定會大有作為。
2、IMG圖片高清化
IMG圖片高清化在前端基本都用判斷不同的屏幕分辨率&userAgent來加載不同分辨率的素材圖片的方式實現。除此之外,還有別的辦法嗎?HTML5的補充說明中增加了srcset屬性,他為開發人員提供了根據設備分辨率而展示不同尺寸的圖像的簡易方法。參考Mat Marquis的文章《WebKit Has Implemented srcset, And It’s A Good Thing》,srcset的使用方法如下所示:
<img src="small.jpg"
srcset="large.jpg 1024w, medium.jpg 640w, small.jpg 320w"
sizes="100vw"
/>
srcset定義了一組提供給瀏覽器的圖片方案。瀏覽器可以根據使用環境或用戶的喜好去決定,它到底是使用一個較低的分辨率的圖片還是使用高分辨率的圖片。目前來看,src的支持程度如下:
三、CSS適配
1、640px設計稿適配
640px設計稿想要適配大屏,一般有兩種方式:media query設置rem基準值或者JS動態計算rem基準值。如下圖所示,拿facebook為例,左邊是facebook的H5官網沒有適配的效果,右邊是本地修改為rem方案的效果,可以看出適配之後icon和文字在大屏下點擊區域整體變大、排版更為緊湊。
(1)media query 設置rem基準值
rem是CSS3新增的一個相對單位(root em,根em)。當用媒體查詢針對不同屏幕改變根元素大小時,頁面也會隨之發生變化。我們可以在css頂部加入以下樣式來實現頁面適應的效果。
/*for >641px with screen*/@media only screen and (min-width: 640px){ html{font-size:200px;}}/*for 480px with screen*/@media only screen and (min-width: 480px) and (max-width: 640px){ html{font-size:150px;}}/*for 400px with screen*/@media only screen and (min-width: 400px) and (max-width: 480px){ html{ font-size:120px;}}/*for 360px with screen*/@media only screen and (min-width: 360px) and (max-width: 400px){ html{ font-size:110px; }}/*for 320px with screen*/@media only screen and (min-width: 320px) and (max-width: 360px){html{ font-size:100px;} }
這種方法的缺點:
通過設備寬度範圍區間這種媒體查詢來動態改變rem的基準值相,其實不夠精確。比如:寬度為320px和寬度為360px的手機,因為屏幕寬度在同一範圍區間內(都<375px),所以會被同等對待(rem基準值相同),而事實上他們的屏幕寬度並不相等,布局也應該有所不同。最終結論就是:這樣的做法,沒有做到足夠的精確,但是夠用。
(2)JS動態計算rem基準值
除了媒體查詢的方法,還有一種通過JS去動態獲取當前屏幕寬度,去精確計算出一個適合該屏幕寬度的rem基準值,這種方法的缺點是對於某些奇數的屏幕寬度(譬如iphone6是375),有些雪碧圖在定位上會存在被裁掉一像素的極端情況。
(function (doc, win) {var docEl = doc.documentElement,resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',recalc = function () { var clientWidth = docEl.clientWidth; if (!clientWidth) return; docEl.style.fontSize = 100 * (clientWidth / 320) + 'px'; }; // Abort if browser does not support addEventListener if (!doc.addEventListener) return; win.addEventListener(resizeEvt, recalc, false); doc.addEventListener('DOMContentLoaded', recalc, false);})(document, window);</script>
(3)頁面元素rem單位轉換
不管是用媒體查詢還是JS的方法,在頁面中加入代碼之後,我們把設計稿中切圖的圖片、文字的長寬大小除以100,對於640的設計稿,如果某張圖片切完圖輸出是100px,只需要把單位換算成100px/100/2=0.50rem即可。這裡把單位設為font-size:100px;,是為了計算方便,當然可以也可以設為font-size:20px;,不建議設為font-size:10px,因為chrome不支持小於12px的字體,在適配過程中會出現誤差。
2、750px設計稿適配
那對於750的設計稿,如果有一個模塊,在psd文件中量出:寬高300×200px的div,我們如何轉換成640設計稿所對應的rem呢?
方法一:在sass中設一個等比變量,模塊寬度乘以等比變量即為320px設計稿寬度(設備寬度320px,對應像素寬度640px)。
$percent:320 / 375 ;.mod{ width:1rem *300 / 2 * $percent /100 ; //2為retina雙倍設計稿,100為在media query中設置的基準值font-size:100px; height:1rem *200 / 2 * $percent /100 ;}
方法二:用sass設一個mixin函數,這樣:
@mixin px2rem($name, $px){ #{$name}: $px / 2 * 320 / 375 * 1rem;}
所以,對於寬高300×200px的div,我們用sass就這樣寫:
.mod{ @include px2rem(width, 300); @include px2rem(height, 200);}
輸出就是:
.mod{
width:1.28rem; height:0.85333rem;}
這樣的寬高,我們往往是這樣得來的:
將750×1334的視覺稿轉成320*568的大小後,再去量這個模塊的大小(感覺好傻)。
在750×1334的設計稿中量得模塊寬高是300×200px後,再拿公式去算得這個模塊的大小(感覺好麻煩)。
方法三:viewport定寬+px(推薦使用)
經過上面複雜的轉換過程,腦細胞快不夠用了。下一步介紹viewport方法,讓你輕輕鬆鬆完成適配。步驟如下:
第一步:把我們以前熟悉的viewport設置從
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no" />
改為:
<meta name="viewport" content="width=375,user-scalable=no" />
第二步:頁面中所有元素按照750設計稿的實際切圖尺寸進行定義,還是拿前面那個寬高300×200px的div舉例,只需要下面這樣定義即可,像素單位還是用回了我們最早期的px,甚至都不用去除以2,因為在viewport中已經換算過了。
.cake{ width:300px; height:200px;}
是不是特別簡單?
優缺點對比:
Rem+Sass方法
缺點:代碼換算複雜。
優點:可以滿足部分模塊固定寬高,不隨屏幕尺寸變化而變的特殊需求。
Viewport方法:
優點:代碼簡單。
缺點:所有模塊跟隨屏幕變化而變化,且不支持在PC設備上查看。
四、總結
移動端的適配方法很多,每一種方法都各有利弊,建議根據自己的項目特點選擇合適的方案組合使用。
提示:感謝您的關注閱讀,本文由 騰訊NDC 版權所有,轉載時請註明出處,違者必究!
LiveMusic是怎樣設計出來的 / Adobe新插件再不用就out了 / App適配一看就會 / 騰訊NDC是做什麼的 / IOS9.0設計師必須要get的重要技能 / BIGBANG最後一場演唱會大禮包里到底發了啥?