概述
這是我研究移動端頁面時的思考,記錄下來供以后開發時參考,相信對其他人也有用。由於我寫移動端頁面寫的還比較少,一些問題都還沒遇到,所以我的這篇博文不免有些錯誤的地方,還請大佬多多指正。
這篇文章是基於網易的移動端屏幕適配方案而來的。
思考
在移動端開發中,對於頁面屏幕適配要解決哪些問題?
- 對於不同的dpr,圖片會有模糊的情況,怎么適配?
- 對於不同的屏幕寬度,怎么適配?
- 對於不同的內容:容器,文字和圖片,怎么適配?
對於移動適配,我個人希望達到的效果是,對於不同的屏幕,在視覺上為了方便閱讀,頁面只需要簡單地放大或縮小即可。但是由於流式布局(根據父容器的百分比來決定寬高)具有很大的局限性,所以我們采用rem布局。
dpr
dpr是什么?簡單來說,dpr是實際像素與看到的像素的比值。比如說你看到的是1px,那么在dpr為2的設備上,它實際上是由2個像素點組成的,每個像素點的實際大小是0.5px。
dpr會造成什么問題?比如一個200px*300px
的圖片,在dpr為1的設備上,顯示正常,但是在dpr為2的設備上,由於實際像素變成了400px*600px
(雖然實際大小仍然只有200px*300px
),那些多余的像素是設備推測出來的,所以會有圖片變模糊的問題。
怎么解決?網上的解決方法說的很復雜,真的聽不懂。。。但是簡單來說,解決方案是使用400px*600px
的圖片,但是規定它的大小為200px*300px
,所以在dpr為1的設備上,圖片是被“壓縮”過的,但是並不影響視覺效果;而在dpr為2的設備上,因為本身的圖片大小是400px*600px
,所以那些多余的px就從這里取了,不會通過設備推測,所以視覺效果會更好。
那么對於dpr>2的設備呢?實際上視覺效果影響不大,可以忽略。等到有足夠的影響成為一個問題之后,再來解決。
屏幕寬度
機制是:對於不同寬度的屏幕,我們用js取到屏幕的寬度,然后根據這個寬度同比縮放font-size,由於我們的css是用rem寫的,所以頁面內容也會同比縮放,達到我們想要的效果。下面具體來講實施方案。
首先給html設置viewport:
<meta name="viewport" content="width=device-width, maximum-scale=1.0, minimum-scale=1.0, initial-scale=1.0, user-scalable=no, viewport-fit=cover">
然后,對於手機端,我們希望以iphone6作為參照,在其它屏幕上同比放大或縮小。
(1)以iphone6作為參照,iphone6的寬度是375px,dpr為2,所以對於上面顯示的375px的圖,我們需要的圖片大小是750px,所以我們拿到的psd設計圖的寬度必須是750px。為了方便書寫rem,我們希望psd設計圖上750px對應的rem是7.5rem。而設計圖上面750px在iphone6上面的實際大小是375px,所以我們需要設置iphone6的font-size=375/7.5px=50px。更一般地,由於移動端的font-size的默認值是16px,所以我們更傾向於用一個百分比來設置font-size:font-size=50/16=312.5%。(注意:用px和百分比沒有本質上的不同。)
(2)在其它屏幕上進行縮放,為了解決這個問題,我們用js來讀取屏幕的寬度,然后利用這個寬度來進行縮放,代碼如下:
var initScreen=function(){
$("html").css("font-size", document.documentElement.clientWidth / 375 * 312.5 + "%");
}
最后,我們需要解決橫屏問題和用戶手動縮放問題,他們本質上都是改變屏幕寬度的問題,所以我們監聽resize事件或者onorientationchange事件,當發生的時候,重新調用initScreen方法。代碼如下:
$(window).on('onorientationchange' in window ? 'orientationchange' : 'resize', function () {
setTimeout(initScreen, 200);
});
注意:上面的代碼並不是原生js,要引入zepto庫!也可以用原生js實現,不過要考慮兼容性問題,我就不貼出代碼了。
另外,為了增加代碼的健壯性,在js加載不成功的時候也能進行適配,建議在css加上媒體查詢:
html{ font-size: 312.5%; }
@media screen and (max-width:359px) and (orientation:portrait) {
html { font-size: 266.67%; }
}
@media screen and (min-width:360px) and (max-width:374px) and (orientation:portrait) {
html { font-size: 300%; }
}
@media screen and (min-width:384px) and (max-width:399px) and (orientation:portrait) {
html { font-size: 320%; }
}
@media screen and (min-width:400px) and (max-width:413px) and (orientation:portrait) {
html { font-size: 333.33%; }
}
@media screen and (min-width:414px) and (max-width:431px) and (orientation:portrait){
html { font-size: 345%; }
}
@media screen and (min-width:432px) and (max-width:479px) and (orientation:portrait){
html { font-size:360%; }
}
@media screen and (min-width:480px)and (max-width:639px) and (orientation:portrait){
html{ font-size:400%;}
}
@media screen and (min-width:640px) and (orientation:portrait){
html{ font-size:533.33%;}
}
容器,文字和圖片
我查了很多資料,對於其它適配方案,比如流式布局,柵格化布局等,都對容器,文字和圖片的尺寸有不同的寫法。但是由於我這個方案只是縮放,並沒有額外的需求,所以對於容器,文字和圖片的大小,都用rem就行了,暫時沒有想出不能用rem的情況,等以后遇到問題再來記錄。
注意:我這種適配方案中,1rem的實際大小是50px,而不是100px。所以0.12rem的字體,在設計稿上面是12px,但是在手機上的實際大小是6px!
其它
還有另外一個很重要的度量單位,vh和vw,以前由於兼容性太差而不太適用,現在逐漸步入時代舞台,比如網易新聞的css里面就有下面這樣一段代碼。(目前vh和vw的適配方案還不成熟,等成熟了我再來記錄。)
@media screen and (max-width: 320px) {
html {
font-size:42.667px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 321px) and (max-width:360px) {
html {
font-size:48px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 361px) and (max-width:375px) {
html {
font-size:50px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 376px) and (max-width:393px) {
html {
font-size:52.4px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 394px) and (max-width:412px) {
html {
font-size:54.93px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 413px) and (max-width:414px) {
html {
font-size:55.2px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 415px) and (max-width:480px) {
html {
font-size:64px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 481px) and (max-width:540px) {
html {
font-size:72px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 541px) and (max-width:640px) {
html {
font-size:85.33px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 641px) and (max-width:720px) {
html {
font-size:96px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 721px) and (max-width:768px) {
html {
font-size:102.4px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 769px) {
html {
font-size:102.4px;
font-size: 13.33333vw
}
}