出來混,那些混過去的,早晚是要還的 ( ̄Д  ̄)┍ 。css
讓咱們來解決幾個問題:html
提到 viewport
,以前總感受挺突兀的,可是當我最近作移動端項目時,忽然關注到一直被忽略的 meta
標籤的時候,才恍然大悟(o(╯□╰)o)。那麼,首先讓咱們來了解一下 meta
標籤☛一直被忽略的meta標籤瞭解一下,以後再去看 viewport
,就很容易記住了,不就是 meta
標籤中 name 屬性的一個值嘛。前端
那麼, 它的做用是啥呢?要了解它具體的做用,咱們須要先來了解一些相關的基本知識。android
viewport
指瀏覽器的窗口,即瀏覽器上用來顯示網頁的那部分區域,是用戶網頁的可視區域。git
viewport
的功能在於控制你網站的最高塊狀(block)容器:<html>
元素。能夠理解爲viewport
是容納<html>
元素的元素。<html>
元素的寬度爲瀏覽器的寬度,即爲viewport
寬度的100%。(原文)github
在移動端和pc端,視口是不一樣的。pc端的視口是瀏覽器窗口區域,而在移動端則有三個不一樣的視口概念:佈局視口
、視覺視口
、理想視口
。web
layout viewport(佈局視口)
:網頁佈局的基準窗口,在PC瀏覽器上,至關於當前瀏覽器的窗口大小(不包括borders 、margins、滾動條)。在移動端,佈局視口被賦予一個默認值,大部分爲980px,這保證PC的網頁能夠在手機瀏覽器上呈現,可是很是小,用戶能夠手動對網頁進行放大。 能夠經過 document.documentElement.clientWidth/clientHeight
獲取網頁在標準模式下的佈局視口大小。visual viewport(視覺視口)
:用戶在移動設備屏幕上能看到的那部分區域。 能夠經過 window.innerWidth / innerHeight
來獲取視覺視口大小。ideal viewport(理想視口)
:網站頁面在移動端展現的理想大小。使頁面的寬度跟設備寬度一致(佈局視口=理想視口 = 視覺視口),咱們就能在移動屏幕上看到正常舒服的頁面。 能夠經過調用 screen.width / height
來獲取理想視口大小。(👉 viewport移動端適配、關於移動端適配,你必需要知道的)c#
viewport
的設置不會對 PC 頁面產生影響,但對於移動頁面卻很重要。segmentfault
屬性 | 含義 | 取值 |
---|---|---|
width | 定義視口的寬度,單位爲像素 | 正整數或設備寬度device-width |
height | 定義視口的高度,單位爲像素 | 正整數或device-height |
initial-scale | 定義初始縮放值 | 整數或小數 |
minimum-scale | 定義縮小最小比例,它必須小於或等於maximum-scale設置 | 整數或小數 |
maximum-scale | 定義放大最大比例,它必須大於或等於minimum-scale設置 | 整數或小數 |
user-scalable | 定義是否容許用戶手動縮放頁面,默認值yes | yes/no |
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
複製代碼
上面這個基本的設置:移動web開發
width=device-width
:表示讓 佈局視口
的寬度等於設備寬度;initial-scale=1
:表示頁面的初始縮放比例爲1,至關於讓 視覺視口
等於 理想視口
;maximum-scale=1.0
表示頁面的最大縮放比爲1;user-scalable=no
表示不容許用戶對頁面進行縮放操做。🌟viewport
屬性的做用,就是讓 佈局視口
經過縮放來適配屏幕寬度,width=device.width
僅僅是讓 佈局視口
初始大小等於設備寬度,後面設置的initial-scale
是用來縮放 佈局視口
大小,並且默認是 佈局視口
初始大小等於設備寬度,也就是所謂的 理想視口
。
rem(font size of the root element):是指相對於根元素的字體大小的單位,其佈局的本質是等比縮放,通常是基於寬度。
將設計稿轉化爲手機屏幕上的內容,就相似於畫地圖,按照必定的比例進行縮小繪製:
dpr ( device pixel ratio):設備像素比,即設備物理像素與邏輯像素(css像素)的比例。
window.devicePixelRatio
複製代碼
設備像素
和 CSS像素
;CSS像素
的大小是可變的,好比用戶縮放頁面的時候,實際上就是在縮小或放大 CSS像素
,而 設備像素
不管大小仍是數量都是不變的。【設計稿】:設計師給的 750px
寬的設計稿是根據設備像素
(device pixel,物理像素
)爲單位制做的設計稿。
【web頁面編寫】:前端工程師在編碼 web 頁面時所寫的 CSS 像素
則須要根據 設備像素比
來進行換算。
設備像素比(DPR) = 設備像素個數 / 理想視口CSS像素個數(device-width) ,則:
CSS像素 = 設計稿像素/dpr。
縮放會影響 佈局視口
的大小,當咱們在移動端對頁面進行放大和縮小時,其實是在改變 CSS 像素的大小,而 scale 縮放的目的就是爲了使 CSS 像素適應移動端的設備像素,而這個縮放是經過兩個關鍵的元素設置來實現的:
width=device-width,initial-scale=1/dpr
作的事情就是先把佈局視口放大dpr倍,而後再總體縮放相應倍數以適應設備尺寸,這樣就可以使css像素和設備物理像素一對一了。
var isAndroid = win.navigator.appVersion.match(/android/gi);
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
// iOS下,對於2和3的屏,用2倍的方案,其他的用1倍方案
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其餘設備下,仍舊使用1倍的方案
dpr = 1;
}
scale = 1 / dpr;
複製代碼
💡rem 是爲了解決不一樣機型不一樣寬度的問題,scale是爲了解決dpr的問題。移動端自適應與dpr是無關的。
淘寶方案中採用了dpr用於解決1px的問題,而網易方案並無引入dpr,佈局視口沒有放大,整個頁面也沒有縮放,可是並不影響與設計圖的比例。
➹ 詳解適配相關概念
明白了上述幾個問題了以後,咱們就掌握了移動端自適應的精髓,從而能夠進行實戰開發了。
經過上面的 rem
換算,咱們可以知道,如何把視覺稿(750px
)中元素的 px
轉換成 rem
。
(1)設置 html font-size,如將手機屏幕分紅10份:
<script>
var dpr = window.devicePixelRatio;
var meta = document.createElement('meta');
// dpr
meta.setAttribute('content', 'initial-scale=' + 1 / dpr + ', maximum-scale=' + 1 / dpr + ', minimum-scale=' + 1 / dpr + ', user-scalable=no');
document.getElementsByTagName('head')[0].appendChild(meta);
// rem
document.addEventListener('DOMContentLoaded', function (e) {
document.getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px';
}, false);
</script>
複製代碼
(2)假設元素寬度爲 300px
,則元素寬度:
能夠經過如下的方案來實現自動轉換:
✔ Scss 方案
$ue-width: 750; /* ue圖的寬度 */
@function px2rem($px) {
@return #{$px/$ue-width*10}rem;
}
p {
width: px2rem(100);
}
複製代碼
✔ vscode 中進行 px
到 rem
的轉換:vscode-cssrem
✔ postcss-pxtorem 方案
// postcss.config.js
const pxtorem = require('postcss-pxtorem');
const pxtoremOpts = {
rootValue: 16, // 根字體大小,默認16
unitPrecision: 5, // 精度
propList: ['font', 'font-size', 'line-height', 'letter-spacing'], // 能夠將px轉換成rem的屬性
selectorBlackList: [], // 選擇器忽略並保留px
replace: true, // 替換包含rems的規則
mediaQuery: false, // 是否容許在媒體查詢中轉換px
minPixelValue: 2 // 設置要替換的最小像素值
};
module.exports = {
plugins: [
pxtorem(pxtoremOpts),
],
};
複製代碼
點擊 DEVICE METRICS 查看更多終端設備的參數。