欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于rem的移動端響應(yīng)式適配方案(詳解)

 更新時間:2017年07月07日 08:44:09   投稿:jingxian  
下面小編就為大家?guī)硪黄趓em的移動端響應(yīng)式適配方案(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

視口

在前一段時間,我曾經(jīng)寫過一篇關(guān)于viewport的文章。最近由于在接觸移動端開發(fā),對viewport有了新的理解。于是,打算重新寫一篇文章,介紹移動端視口的相關(guān)概念。

關(guān)于這篇文章說到的所有知識,本質(zhì)上離不開以下代碼

<meta name="viewport" content="width=device-width, initial-scala=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />

@media all and (max-width: 320px) {
 // do something
}

了解過移動端開發(fā)的朋友,其實(shí)對以上的代碼就不會陌生。上面的代碼,主要涉及到meta視口標(biāo)簽與媒體查詢。單單以上簡短的代碼就需要明白:

像素(pixel)

視口(viewport)

分辨率(resolution)

meta視口標(biāo)簽

媒體查詢(media query)

JavaScript相關(guān)的屬性和方法

如何實(shí)現(xiàn)移動端響應(yīng)式適配的問題

那就進(jìn)入主題吧:)

像素

在移動端上,所謂的像素分為兩種

CSS像素:CSS像素就是我們在編寫CSS代碼時的像素。

設(shè)備像素:設(shè)備屏幕的物理像素,任何設(shè)備的物理像素的數(shù)量都是固定的。

1個CSS像素等于多少個設(shè)備像素取決于屏幕特性(是否是高清屏)和用戶縮放的比例。當(dāng)用戶將屏幕從100%放大到200%時,1個CSS像素等于2個設(shè)備像素,反之相反;當(dāng)屏幕為Retina高清屏(如iPhone6,dpr=2)時,1個CSS像素就等于2個設(shè)備像素,反之相反。

需要明白一點(diǎn)的是,2個設(shè)備像素并不是說它擴(kuò)大了兩倍,而是說在頁面上仍然顯示的是1px(1個CSS像素),但是這1px是由2個設(shè)備像素組成。像素點(diǎn)變多了,因此圖像會變得更加清晰。下面這幅圖大致說明了CSS像素和設(shè)備像素的區(qū)別。

視口

在移動端上,存在三種不同的視口。

布局視口:在PC端上,布局視口等于瀏覽器窗口的寬度。而在移動端上,由于要使為PC端瀏覽器設(shè)計(jì)的網(wǎng)站能夠完全顯示在移動端的小屏幕里,此時的布局視口會遠(yuǎn)大于移動設(shè)備的屏幕。在移動端,默認(rèn)情況下,布局視口等于瀏覽器窗口寬度。布局視口限制了CSS的布局。在JavaScirpt上獲取布局視口的寬度可以通過document.documentElement.clientWidth | document.body.clientWidth得到。

視覺視口:視覺視口是用戶正在看到的區(qū)域。用戶可以縮放來操作視覺視口,而不影響視覺視口的寬度。視覺視口決定了用戶看到了什么。在JavaScript上獲取視覺視口的寬度可以通過`window.innerWidth得到。

在PC端上,視覺視口等于布局視口的寬度,無論用戶是放大屏幕還是縮小屏幕,這兩個視口的寬度仍然相等。但是,在移動端上,并非如此??s放屏幕的過程實(shí)質(zhì)上就是CSS像素縮放的過程。當(dāng)用戶將屏幕放到到兩倍時,視覺視口變小了(因?yàn)橐曈X視口中CSS像素變少了),而每單位的CSS像素卻變大了,因此1px(1個CSS像素)等于2個設(shè)備像素。同理,當(dāng)為iPhone6(dpr=2)時,視覺視口中CSS像素變少了,但是1px等于2個設(shè)備像素。當(dāng)用戶縮小屏幕時也是同樣的道理??s放的過程并不會影響布局視口的大小。

也就是說,高清屏(dpr>=2)或屏幕放大時,視覺視口變小(CSS像素變少),每單位的CSS像素等于更多的設(shè)備像素;非高清屏(dpr<2)

或屏幕縮小時,視覺視口變大(CSS像素變多),每單位的CSS像素等于更少的設(shè)備像素。

但是無論放大或縮小屏幕,布局視口的寬度仍然保持不變。

理想視口:由于默認(rèn)情況下布局視口等于瀏覽器窗口寬度,因此在移動端上需要通過放大或縮小視覺視口來查看頁面內(nèi)容,這當(dāng)然體驗(yàn)糟糕??!因此在移動端引入了理想視口的概念。理想視口的出現(xiàn)必須需要設(shè)置meta視口標(biāo)簽,此時布局視口等于理想視口的寬度。常見的,iPhone6的理想視口為375px * 667px,iPhon6 plus的理想視口為414px * 736px。在JavaScript上獲取視覺視口的寬度window.screen.width得到。

<meta name="viewport" content="width=device-width" />

當(dāng)設(shè)置了meta視口標(biāo)簽之后,iPhone6的布局視口寬度將等于375px,iPhone6plus布局視口的寬度等于414px。其他移動設(shè)備相似。

理想視口會隨著屏幕的旋轉(zhuǎn)而改變。當(dāng)iPhone6為肖像模式時(即豎屏),此時理想視口為375px * 667px;但為橫屏模式時,此時理想視口為667px * 375px。

分辨率與設(shè)備像素比

分辨率是指每英寸內(nèi)點(diǎn)的個數(shù),單位是dpi或者dppx。設(shè)備像素比是指設(shè)備像素與理想視口寬度的比值,沒有單位。

分辨率在CSS上可以通過resolution屬性設(shè)置。一般情況下會使用dpi作為分辨率的單位,因?yàn)閐ppx并非所有瀏覽器都支持。

而設(shè)備像素比在CSS上可以通過device-device-pixel-ratio屬性設(shè)置,而在JavaScript上可以通過window.devicePixelRatio屬性獲取。

同時,1dpr=96dpi。舉個例子。在iPhon6下,理想視口寬度為375px,而設(shè)備像素為750px,因此此時設(shè)備像素比為2,分辨率為192dpi。因此如果為iPhon6以下的設(shè)備寫某個特定樣式,可以這樣寫

// 注意,device-pixel-ratio需要帶上-webkit-前綴,保證瀏覽器兼容性問題。
@media all and (max-width: 375px) and (-webkit-max-device-pixel-ratio: 2) {
 body {
 background-color: red;
 }
}
或者
@media all and (max-width: 375px) and (max-resolution: 192dpi) {
 body {
 background-color: red;
 }
}

meta視口標(biāo)簽

meta視口標(biāo)簽是是設(shè)置理想視口的重要元素,主要用于將布局視口的尺寸和理想視口的尺寸相匹配。meta視口標(biāo)簽存在5個指令

width:設(shè)置布局視口的寬度,一般設(shè)為device-width。

initial-scale:初始縮放比例。1即100%,2即200%,以此類推

maximum=scale:最大縮放比例。

minimum-scale:最小縮放比例。

user-scalable:是否靜止用戶進(jìn)行縮放,默認(rèn)為no。

需要注意的是,縮放是根據(jù)理想視口進(jìn)行計(jì)算的。縮放程度與視覺視口的寬度是逆相關(guān)的。也就是說,當(dāng)你將屏幕放到到2倍時,視覺視口為理想視口的一半,此時每單位的CSS像素等于2個設(shè)備像素。縮小時則相反。

響應(yīng)式適配問題

理解了一些基本概念之后,我們來看看如何實(shí)現(xiàn)響應(yīng)式適配。

一般情況下,前端開發(fā)工程師會根據(jù)設(shè)計(jì)師給的設(shè)計(jì)稿進(jìn)行開發(fā)。而設(shè)計(jì)稿一般是根據(jù)iPhon6手機(jī)進(jìn)行頁面的設(shè)計(jì)的。我們知道iPhone6的理想視口寬度為375px,同時iPhone6的設(shè)備像素比為2,設(shè)備像素為750px。我們需要在只有一份設(shè)計(jì)稿的情況下寫出適應(yīng)各種屏幕不一的終端設(shè)備,因此需要一些移動端響應(yīng)式適配的方案。此時需要用到的一個單位是REM。簡單的說,REM會根據(jù)HTML元素的font-size進(jìn)行設(shè)置。當(dāng)HTML元素的font-size: 16px時,1rem = 16px, 1.5rem = 24px

個人總結(jié)出了兩套響應(yīng)式適配的方案(前提是設(shè)置meta視口標(biāo)簽)。兩套方案由一個共同點(diǎn):給定一個基準(zhǔn)值。

假如現(xiàn)在拿到的設(shè)計(jì)稿是根據(jù)iPhone6進(jìn)行設(shè)計(jì)的。

方案一

方案一是設(shè)計(jì)稿給什么尺寸,我們就將其縮小100倍,最后換算成rem單位。比如,設(shè)計(jì)稿上某個title的font-size為32px,此時寫CSS樣式時就直接縮小100倍,即0.32rem。

由于rem是根據(jù)根元素進(jìn)行設(shè)置的,所以我們需要設(shè)置根元素的font-size。

給HTML設(shè)置font-size的基本思路:

通過window.screen.width獲取不同移動設(shè)備的理想視口寬度。

規(guī)定基準(zhǔn)值為750px(此值為iPhon6的設(shè)備像素)。

(1) / (2) * 100即得到HTML元素的font-size。(乘于100是因?yàn)槲覀冊谇懊鎸⒆煮w縮小了100倍,此時要乘回來)

換算成公式即:設(shè)計(jì)稿尺寸 / 100 * (不同設(shè)備的理想視口寬度 / 基準(zhǔn)值 * 100)

舉個例子。

// 根據(jù)不同設(shè)備的理想視口寬度動態(tài)設(shè)置根元素的`font-size`。
let idealViewWidth = window.screen.width;
const BASICVALUE = 750;
document.documentElement.style.fontSize = (idealViewWidth / BASICVALUE) * 100 + 'px';

因此,在不同設(shè)備下的HTML元素的font-size大小和實(shí)際像素如下

iPhone5 : (320 / 750) * 100 = 42.667px
iPhone6 : (375 / 750) * 100 = 50px
iPhone6+: (414 / 750) * 100 = 55.2px

假如設(shè)計(jì)稿上標(biāo)注.title類上的字體為32px,此時有

iPhone5上的某字體: 42.667 * 0.32rem = 13.653px
iPhone6上的某字體: 50 * 0.32rem = 16px
iPhone6+上的某字體: 55.2 * 0.32rem = 17.664px

可以看出,在不同設(shè)備下,同一字號的字體使用rem單位可以實(shí)現(xiàn)不同設(shè)備的響應(yīng)式適配。不單單在字體上可以使用,在移動端上的width、height等涉及單位的都可以使用。這樣的話,就可以在不同設(shè)備下完美的復(fù)現(xiàn)設(shè)計(jì)稿的要求。

方案二

此方案使用了SASS預(yù)處理器。基本思路:

設(shè)置根元素的font-size。通過獲取不同設(shè)備的理想視口寬度,再除以10。(除以10是因?yàn)椴幌雈ont-size太大。)

給定基準(zhǔn)值,此時給的基準(zhǔn)值為75px(此值為iPhone6的設(shè)備像素除以10)

寫SASS Function

代碼如下

SASS
@function px2rem ($value) {
 $para: 75px;
 @return $value / $para + rem;
}

JS
let idealViewWidth = window.screen.width;
document.documentElement.style.fontSize = idealViewWidth / 10 + 'px';

在不同設(shè)備下根元素的`font-size`:

iPhone5 : 320px / 10 = 32px
iPhone6 : 375px / 10 = 37.5px
iPhone6+: 414px / 10 = 41.4px

根據(jù)以上,可以看一個例子。某設(shè)計(jì)稿下5個li,橫向排布,每個的寬度為200px
CSS
@import (路徑名)
iPhone5: li { width: px2rem(200px) } => width: 85.333px
// 此時(200px / 75px = 2.667rem) 2.667rem = 2.667 * (320 / 10) = 85.3333px
iPhone6: li { width: px2rem(200px) } => width: 100px
// 此時(200px / 75px = 2.667rem) 2.667rem = 2.667 * (375 / 10) = 100px
iPhone6+: li { width: px2rem(200px) } => width: 4138px
// 此時(200px / 75px = 2.667rem) 2.667rem = 2.667 * (414 / 10) = 110.4138px

因此,一個200px的(實(shí)際只有100px)的li元素的寬度在不同設(shè)備下顯示了不同的寬度,實(shí)現(xiàn)了響應(yīng)式適配的問題。

方案三

方案三與前兩個方案不相同,此方案并不需要給根元素設(shè)置font-size,不需要基準(zhǔn)值。此方案是根據(jù)不同設(shè)備的dpr來實(shí)現(xiàn)頁面的縮放的。

基本思路如下:

通過window.devicePixelRatio獲取設(shè)備的dpr

根據(jù)不同的dpr縮放頁面,動態(tài)設(shè)置meta視口標(biāo)簽。(縮放是放大或縮小CSS的過程,根據(jù)理想視口進(jìn)行縮放,與視覺視口方向相反)

代碼如下:

let dpr = window.devicePixelRatio;
let meta = document.createElement('meta');
let initialScale = 1 / dpr;
let maximumScale = 1 / dpr;
let minimumScale = 1 / dpr;
meta.setAttribute('name', 'viewport');
meta.setAttribute('content', `width=device-width, user-scalable=no, initial-scale=${initialScale}, maximum-scale=${maximumScale}, minimum-scale=${minimumScale}`);
document.head.appendChild(meta);

因此,可以直接根據(jù)設(shè)計(jì)稿的尺寸寫CSS樣式,如設(shè)計(jì)稿下有5個li元素,寬度為200px,此時不同設(shè)備下li的寬度

iPhone5 : li { width: 200px } 實(shí)際寬度為:100px
iPhone6 : li { width: 200px } 實(shí)際寬度為:100px
iPhone6+: li { width: 200px } 實(shí)際寬度為:66.667px

以上三種方法解決了大部分移動端響應(yīng)式適配的問題,但是在1px問題上,使用以上的方法仍然(除了第三個方案),都不能很好的解決1px的問題。有時間寫一篇文章介紹如何解決1px的問題。

以上這篇基于rem的移動端響應(yīng)式適配方案(詳解)就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論