自適應總結

原理:

物理像素:

一個物理像素是顯示器(手機屏幕)上的最小物理顯示單元。

設備獨立像素:

設備獨立像素(密度無關像素),可以認為是計算機坐標系統(tǒng)中得一個點,這個點代表一個可以由程序使用的虛擬像素(比如: css像素),然后由相關系統(tǒng)轉換為物理像素。

設備像素比:

設備像素比(簡稱dpr)定義了物理像素和設備獨立像素的對應關系,它的值可以按如下的公式的得到:

    設備像素比 = 物理像素 / 設備獨立像素 // 在某一方向上,x方向或者y方向

在javascript中,可以通過window.devicePixelRatio獲取到當前設備的dpr。

以iphone6為例子:
1、設備寬高為375×667,可以理解為設備獨立像素(或css像素)。
2、dpr為2,根據上面的計算公式,其物理像素就應該×2,為750×1334。

image.png

我們稱dpr大于1的屏幕為高清屏(retina)。

對于:

width: 2px;
height: 2px;

在不同的屏幕上(普通屏幕 vs retina屏幕),css像素所呈現的大小(物理尺寸)是一致的,不同的是1個css像素所對應的物理像素個數是不一致的。

在普通屏幕下,1個css像素 對應 1個物理像素(1:1)。 在retina 屏幕下,1個css像素對應 4個物理像素(1:4)。

引入原因:
retina下,border: 1px問題

那么retina顯示屏的優(yōu)勢在哪里,設計師為何覺得高清屏下(右圖)這個線條粗呢?明明和左右一樣的~

image.png

上圖中,對于一條1px寬的直線,它們在屏幕上的物理尺寸(灰色區(qū)域)的確是相同的,不同的其實是屏幕上最小的物理顯示單元,即物理像素,所以對于一條直線,iphone5它能顯示的最小寬度其實是圖中的紅線圈出來的灰色區(qū)域,用css來表示,理論上說是0.5px。

所以,設計師想要的retina下border: 1px;,其實就是1物理像素寬,對于css而言,可以認為是border: 0.5px;,這是retina下(dpr=2)下能顯示的最小單位。 然而,無奈并不是所有手機瀏覽器都能識別border: 0.5px;,ios7以下,android等其他系統(tǒng)里,0.5px會被當成為0px處理,那么如何實現這0.5px呢?

然而,無奈并不是所有手機瀏覽器都能識別border: 0.5px;,ios7以下,android等其他系統(tǒng)里,0.5px會被當成為0px處理,那么如何實現這0.5px呢?

1、簡單的做法
.scale{
     position: relative;
}
.scale:after{     
    content:"";     
    position: absolute;     
    bottom:0px;     
    left:0px;     
    right:0px;    
    border-bottom:1px solid #ddd;
       webkit-transform:scaleY(.5); 
       webkit-transform-origin:0 0; 
 }

我們照常寫border-bottom: 1px solid #ddd;,然后通過transform: scaleY(.5)縮小0.5倍來達到0.5px的效果,但是這樣hack實在是不夠通用(如:圓角等),寫起來也麻煩。

2、推薦的做法
<meta name="viewport" content="width=640,initial-scale=0.5,maximum-scale=0.5, minimum-scale=0.5,user-scalable=no">

這樣,頁面中的所有的border: 1px都將縮小0.5,從而達到border: 0.5px;的效果。

縮放的公式:
var dpr = window.devicePixelRatio;
var ratio = 1 / dpr;
var content = 'width=device-width, initial-scale=' + ratio + ', user-scalable=no, minimum-scale=' + ratio + ', 
maximum-scale=' + ratio;
viewport.setAttribute('content', content);

這樣頁面就根據dpr的值來進行對應的縮放。

然而,頁面scale,必然會帶來一些問題:

1、字體大小會被縮放
2、頁面布局會被縮放(如: div的寬高等)

多屏適配布局問題:

移動端布局,為了適配各種大屏手機,目前最好用的方案莫過于使用相對單位rem。
基于rem的原理,我們要做的就是: 針對不同手機屏幕尺寸和dpr動態(tài)的改變根節(jié)點html的font-size大小(基準值)。

對于M站:

因為UI從來是拿iphone6的標注來給前端,所以我們直接用iphone6的標準。

根據rem,iphone6下的font-size應該是 32px 得出一個比率稱為bRate = 750 / 32; bRate: 23.4275; 所以一切其他的手機屏幕都可以圍繞這個bRate設置font-siez基準值。

    fontSize = document.documentElement.getBoundingClientRect().width / bRate 
    htmls.setAttribute('style', 'font-size: ' + fontSize + 'px');

這樣實現了根據不同的屏幕寬度和dpr來實現不同響應式布局,很好的解決了border: 1px問題,也真正用到了rem。

好處:
1、 border: 1px問題。
2、 解決了以前根據屏幕寬度來手動做適應的是問題,比如iphone4上展示兩個標簽,iphone6上展示4個標簽這種問題。

如果將rem轉為為px :
ipone6下 將 xxxrem 轉換為 px的方法 xxx * 32 即可

要求:

由于引入了rem,會對開發(fā)人員有一點點要求:

1、不能在html.tpl中的 styl里面寫 px,所有的style都寫在樣式表里面。

不允許:

<p style=”height: 40px;width: 40px;”> </p> 
<img src=”xxx” width=”120”, height=”130”>

推薦:

<p class=”setHeight”></p> 
<img src=”xxx” class=”myImg”>

2、不能在js中的寫px,所有的位置計算,都以一個dom為基準計算,不允許平白無故寫px。

不允許:

     $(‘.mydom’)
              .css(
                  { height: ‘40px’ }
                );

     if ($(‘.myDom’).height > 100)

推薦:

$(‘.mydom’).addClass(‘setHeight’); 

if ($(‘.myDom’).height > $(‘.otherDom’).height)

3、不推薦在html里面拼大量的字符串,如果需要前端渲染模板,不推薦寫在Js里面,而是用artTemplate進行渲染。

如果只有一兩行的html話

不允許:

var s = ‘<p style=”height: 30px”></p>’;

推薦:

var s =’<p class=”myStyle”></p>’

不兼容問題:

1、富文本:

富文本中可以自己定義px,會造成部分被縮放的問題,所以建議凡是引用富文本的地方建議進行過濾處理。
過濾函數 M1,M2 common/function/transToRem.js

2、播放器:

由于每個手機原生的H5 video標簽的播放器都不一樣,所以不推薦有播放器的頁面進行自適應縮放。
(會有播放進度條和播放按鈕過被壓縮過小的問題,如果PM接受可以用縮放)。

3、嵌入外部網頁的iframe

如果要嵌入主站的iframe或者別的網站的iframe的話(子頁面沒設置fontSize的話),也不推薦使用縮放。
這種頁面M站有 引用百家云SDK播放器、百度地圖。

開關:

模板:針對上述情況,在M1、M2中設置了開關,只需要在入口模板中的

image.png

加{{$isNeedScale = false}}

js: TODO: 暫時還沒提取,會提取一個公共js來判斷js是否被縮放開關。

M2的react TODO: 暫時還沒提取,會提取一個公共js來判斷js縮放開關。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 一、meta標簽的效果 移動端頁面一般會在head頭部添加如下meta標簽。 該meta標簽是否添加對頁面渲染的影...
    nimw閱讀 3,798評論 0 5
  • 問題的由來 手機屏幕的分辨率差異很大。 iphone4:320×480 iphone6:375×667 H5 網頁...
    尚山夏香閱讀 2,589評論 0 1
  • 為什么模擬器下iP6的分辨率為375*667而設計圖一般給750*1334? PPI:每英寸內有多少物理像素點(設...
    LoveBugs_King閱讀 2,401評論 0 0
  • 今天是第三十二個教師節(jié),我作為一名教師,祝所有的教師朋友們節(jié)日快樂,祝福教師們身體健康、平安,也希望我的教師朋友...
    南山臺子閱讀 218評論 1 0
  • (一) 清順治初年,大明遺臣參將馬雄飛駐守香山(今廣東珠海)反清。 因患病日久,禱觀世音菩薩以求消災。后來夢中感菩...
    Derek_Kun閱讀 2,493評論 0 2

友情鏈接更多精彩內容