移動端適配基礎概念和適配方案
物理像素與設備獨立像素:
概念:
分辨率指的是物理像素,物理像素即設計圖的像素以及css中的像素。
設備獨立像素:實際的視窗口大小。
設備像素比:
每款設備的devicePixelRatio都是已知,並且不變的,目前高清屏,普遍都是2,不過還有更高的,比如2.5, 3 等,魅族note的手機devicePixelRatio就是3。
devicePixelRatio*scale(scale為viewport裏設置的值)=屏幕物理像素(與css相對應)/設備獨立像素(邏輯像素)。
devicePixelRatio是window對象的一個屬性,它被大多數的webkit瀏覽器所支持。當devicePixelRatio值等於1時(也就是最小值),那麽它普通顯示屏,當devicePixelRatio值大於1(通常是1.5、2.0),那麽它就是高清顯示屏。
高清屏(Retina)和普通屏區別:
相同區域的物理像素點數,高清屏是普通屏的幾倍。
retina是高清屏,普通屏幕的1個CSS像素點對應4個高清屏幕的像素點,1個分成4個,不夠分的情況下,顏色會取近似值。所以在普通屏幕正常顯示的圖片,在高清屏上會變的模糊。
兼容高清屏:裁切圖是2倍圖(以高清屏的要求去裁切),在css中使用的時候會使用css設置的尺寸為裁切圖的一半。因為在高清屏中使用普通圖片的時候,同樣的css尺寸,圖片被放大了。
設備寬度320像素,當使用<meta name="viewport" content="width=device-width">,視窗的布局寬度
對於iphone4s來說,當屏幕縱向顯示的時候,屏幕的物理像素是640像素,而視區寬度不是640像素而是320像素。屏幕的物理像素為640像素,獨立像素還是320像素,window.devicePixelRatio=2。
適配普通屏和高清屏的方案
根據不同的設備像素比來加載不同的圖片:
- 針對普通顯示屏(devicePixelRatio = 1.0、1.3),加載一張1倍的圖片
- 針對高清顯示屏(devicePixelRatio >= 1.5、2.0、3.0),加載一張2倍大的圖片
(1)使用css 的media queries來加載不同圖片(意味要切兩套圖片1倍圖和2倍圖):
示例的demo如下:
.css{/* 普通顯示屏(設備像素比例小於等於1.3)使用1倍的圖 */
background-image: url(img_1x.png);
}
@media only screen and (-webkit-min-device-pixel-ratio:1.5){
.css{/* 高清顯示屏(設備像素比例大於等於1.5)使用2倍圖 */
background-image: url(img_2x.png);
}
}
CSS Media Queries的優點
- 只有對應的目標元素才會下載圖片資源
- 跨瀏覽器兼容
- 像素可以精確控制
CSS Media Queries的缺點
- 單調無味的實現過程,特別是大型項目中
- 只能通過HTML元素的背景圖片來實現,無任何語義化可言
(2)JavaScript的解決方案
使用js對"window.devicePixelRatio"進行判斷,然後根據對應的值給Retina屏幕選擇圖像。
$(document).ready(function(){
if (window.devicePixelRatio > 1) {
var lowresImages = $(‘img‘);
images.each(function(i) {
var lowres = $(this).attr(‘src‘);
var highres = lowres.replace(".", "@2x.");
$(this).attr(‘src‘, highres);
});
}
});
Javascript查詢的優點
- 易於實施
- 非Retina屏幕不用下載過大的資源
- 像素精確控制
Javascript查詢的缺點
- Retina屏幕下必須下載標準和高精密度的兩個資源
- Retina屏幕下圖像交互可見
- 瀏覽器兼容性不強
(3)使用SVG矢量圖像
SVG矢量圖的優點
- 一個資源適合所有設備
- 易於維護
- 面向未來的:可伸縮向量圖形
SVG矢量圖的缺點
- 沒有像素那樣有精度
- 由於文件大小,不適合復雜的圖形
- 不支持IE7-8和早期的安卓版本
em與rem的區別:
推文:
http://caibaojian.com/rem-vs-em.html
rem 取決於 html 元素的字體大小。
em相對於使用em單位的元素的字體大小,像素值是em值乘以使用em單位的元素的字體大小。父元素的字體大小可以影響 em 值,但這種情況的發生,純粹是因為繼承。 當 em 單位設置在 html 元素上時,它將轉換為em值乘以瀏覽器字體大小的設置。
html——div——padding——1.5em
f-s:16px——16px——16*1.5=24px
html——div——div——padding
f-s:16px——1.25em(20px)——20px——20*1.5=30px
由於存在著這些隱患,所以必須知道如何正確管理使用 em 單位。
默認情況下瀏覽器通常有字體大小 16px,但這可以被用戶更改為從 9px 到 72px的任何值。
正確使用rem和em的場景:
使用 rem 單位的主要目的應該是確保無論用戶如何設置自己的瀏覽器,我們的布局都能調整到合適大小。
//如果您確實需要更改 html 元素的字體大小,那麽就使用em,rem單位,這樣根元素的值還會是用戶瀏覽器字體大小的乘積。
em 單位的主要目的應該是允許保持在一個特定的設計元素範圍內的可擴展性。
當使用 em 單位,他們使用的元素的字體大小應設置對rem單位,以保留的可擴展性,但避免繼承混淆。一般使用 rem 單位的字體大小,em 單位只在特殊的情況下使用。
通常不使用 em 單位控制字體大小。
不要使用 em 或 rem :
布局中的列寬通常應該是 %,因此他們可以流暢適應無法預知大小的視區。然而單一列一般仍然應使用 rem 值來設置最大寬度。
偶爾會遇到真的需要使用顯式的固定的值,以防止縮放的元素。
布局:
flex布局詳細實例:
https://www.cnblogs.com/lynnmn/p/6262941.html
適配方案
流式布局:
寬度使用百分比,高度固定。大屏幕下,會被橫向拉伸變形,設計起來也有局限性,有兼容性,大量百分比也不好計算。
固定寬度:
固定寬度,超出部分留白,大屏幕手機下看起來頁面會特別小,操作的按鈕也很小
響應式:
工作大,維護性難,一般都是中小型的門戶或者博客類站點會采用響應式的方法從web page到web app直接一步到位,因為這樣反而可以節約成本,不用再專門為自己的網站做一個web app的版本。
設置viewport進行縮放:
例如以320寬度為基準,進行縮放,最大縮放為320*1.3 = 416,基本縮放到416都就可以兼容iphone6 plus的屏幕了,這個方法簡單粗暴,又高效。不過有反應縮放會導致有些頁面元素會糊的情況。·
<meta name="viewport" content="width=320,maximum-scale=1.3,user-scalable=no">
使用flexbox
https://www.cnblogs.com/lynnmn/p/6262941.html
rem等比例適配所有屏幕:
· 根據不同的屏幕算出html的font-size,而頁面內的大小單位都用rem來寫,利用rem單位相對根元素的font-size來做計算,從而實現了自適應。
設計圖尺寸與適應尺寸之間的換算:
推文:
http://caibaojian.com/mobile-responsive-example.html
方案一:
scale設置為1,整個網頁在設備內顯示時的頁面寬度就會等於設備邏輯像素大小(實際的視窗口大小),比如設計稿橫向分辨率為640px,為了計算方便,取一個100px的font-size為參照,那麽body元素的寬度就可以設置為width: 6.4rem,於是html的font-size=deviceWidth / 6.4。這個deviceWidth就是viewport設置中的那個deviceWidth。
這個deviceWidth通過document.documentElement.clientWidth就能取到了,所以當頁面的dom ready後,做的第一件事情就是:·
document.documentElement.style.fontSize = document.documentElement.clientWidth / 6.4 + ‘px‘;
註意兩點:
視口要如下設置:
<meta name="viewport" content="initial-scale=1,maximum-scale=1, minimum-scale=1">
相關知識點:[S3-E415]常用meta整理
當deviceWidth大於設計稿的橫向分辨率時,html的font-size始終等於橫向分辨率/body元素寬:
因為當deviceWidth大於640時,則物理分辨率大於1280(這就看設備的devicePixelRatio這個值了),應該去訪問pc網站了。
var deviceWidth = document.documentElement.clientWidth;
if(deviceWidth > 640) deviceWidth = 640;
document.documentElement.style.fontSize = deviceWidth / 6.4 + ‘px‘;
方案二:
當scale根據devicePixelRatio動態設置,每款設備的devicePixelRatio都是已知,並且不變的,目前高清屏,普遍都是2,不過還有更高的,比如2.5, 3 等。
1、動態設置scale:
var scale = 1 / devicePixelRatio;
document.querySelector(‘meta[name="viewport"]‘).setAttribute(‘content‘,‘initial-scale=‘ + scale + ‘, maximum-scale=‘ + scale + ‘, minimum-scale=‘ + scale + ‘, user-scalable=no‘);
deviceWidth=物理分辨率/(devicePixelRatio * scale)——》deviceWidth=物理分辨率=document.documentElement.clientWidth(和方案一一樣)
2、font-size = deviceWidth / 100:——》font-size
3、當橫向分辨率達到某個臨界點,deviceWidth就等於某個值
總結:方案二肯定的用計算器。。但是使用css處理器的話就好辦了:
但是上面兩種方法的font-size都是使用媒體查詢做的,使用js能適配所有。
更改html的font-size,一種是使用js(能適配所有尺寸)—— flexible.js。
一種使用媒體查詢(適配部分設備,一般在做web app都會先統計網站有哪些主流的屏幕設備,然後去針對那些設備去做media query設置也可以實現適配)
flexible.js如何實現rem自適應
移動端適配基礎概念和適配方案