@(概述)[基本概念|百分比|rem|vw/vh|響應式設計]
移動端web頁面的開發,由于手機屏幕尺寸、分辨率不同,或者需要考慮橫豎屏問題,為了使得web頁面在不同移動設備上具有相適應的展示效果,需要在開發過程中使用合理的適配方案來解決這個問題。
早期網頁設計采用靜態布局,通過<meta>
標簽中的applicable-device
應用設備標識識別移動設備,即<meta name = 'applicable-device' content = 'mobile'>
,在<meta>
標簽中的viewport
標簽中設置width
,通過js
動態修改標簽的initial-scale
使得頁面等比縮放,剛好占滿整個屏幕。一些文章中有提到靜態布局中頁面各個元素采用px
為單位,這種方案實現簡單,不存在兼容性問題,但用戶體驗很不友好。
后面出現流式布局,使用百分比%
定義寬度,高度使用px
固定,根據可視區域大小實時進行尺寸調整,通常使用max-width/min-width
控制尺寸范圍過大或者過小。這種方案實現比較簡單,但在大屏手機或橫豎屏切換場景下可能會導致頁面元素被拉伸變形,字體大小無法隨屏幕大小發生變化。
順應不同頁面字體大小展現問題,出現了彈性布局。這種布局方案下,包裹文字的元素的尺寸采用em/rem
為單位,頁面主要劃分區域的尺寸依據情況使用px
、百分數或者em/rem
。如一些高校的網站 jlu,頁面的主要劃分區域使用px
和百分比,包裹文字的元素和文字采用em
。
上面的這幾種方案下,頁面元素的大小按照屏幕分辨率進行適配調整,但是整體布局不變,對于響應式web設計,網頁布局會隨著訪問它的視口及設備的不同呈現不同的樣式,在實現上可能會以上多種方案的結合,同時搭配 媒體查詢 技術使用,使得一個頁面在多個終端 (PC, mobile, pad) 呈現滿意效果,如 mashable 。
[TOC]
基本概念
像素
px (pixel)
像素,是屏幕上顯示數據的最基本的點,表示相對大小。不同分辨率下相同長度的px
元素顯示會不一樣,是因為像素點的個數相同情況下,不同分辨率下每個像素點對應的像素寬度不同。比如同樣是14px
大小的字,在1366×768
顯示屏下會顯示的小,在1024×768
顯示屏下會相對大。也稱為 物理像素(設備像素),是分辨率的尺寸單位。
pt (point)
印刷行業常用單位,能夠使用測量設備測得的長度,等于1/72
英寸。
css像素
在不同屏幕上,css
像素呈現的物理尺寸一致,但css
像素對應的物理像素具數不同。標準的顯示密度下,1
個css
像素對應一個物理像素,縮放時,1
個css
像素對應的物理像素會減增。是一種設備獨立像素(device independent pixels: DIPs)
PPI (pixel per inch)
像素密度,每英寸所擁有的像素數。值越高,顯示畫面細節越豐富。計算公式為:,其中
和
是分辨率的寬高,
是屏幕尺寸。
DPI (dot per inch)
打印設備每英寸印刷出來的點有多少個,值越高,圖片越細膩。
DPR (devicePixelRatio)
設備物理像素和設備獨立像素比,即是指在理想布局寬度,使用多少個物理像素來渲染一個css像素。js中通過
window.devicePixelRatio
獲取,css中通過-webkit-device-pixel-ratio
,-webkit-min-device-pixel-ratio
,-webkit-max-device-pixel-ratio
進行媒體查詢。
視口
<meta>
標簽中定義了一些元數據信息,通過設置<meta name = "viewport">
,提供有關 視口初始大小 的信息,供移動設備 使用。屬性值為
屬性 | 屬性值 | 描述 |
---|---|---|
width |
數值 / device-width
|
視口寬度 |
height |
數值 / device-height
|
視口高度 |
initial-scale |
0.0 ~ 10.0 | 設備寬度與視口大小之間的縮放比率 |
maximum-scale |
0.0 ~ 10.0 | 縮放最大值 |
minimum-scale |
0.0 ~ 10.0 | 縮放最小值 |
user-scalable |
布爾值 | 默認yes ,為no 時用戶不能縮放網頁 |
移動端涉及布局視口(Layout Viewport)、視覺視口(Visual ViewPort)和理想視口(Ideal ViewPort)。
-
布局視口是指用視口元標簽(viewport meta)來進行布局視口設置,
css
布局是相對于布局視口計算
... -
視覺視口是指用戶當前看到的區域
... -
理想視口是屏幕分辨率的值,通過設置
<meta name = "viewport" content = "width = device-width, initial-scale = 1.0">
實現
手機屏幕特性
與移動端web頁面適配有關的手機屏幕特性包括
像素分辨率
硬件所支持的,屏幕每行的像素*
每列的像素點數,單位是px
。
邏輯分辨率
設備獨立的,軟件可以達到的,個人理解是使得軟件/頁面在不同屏幕上顯示出來的效果一致。
倍率
像素分辨率÷
邏輯分辨率等于倍率,如@3x
表示分辨率的3
倍。一個已知物理像素大小的元素,如果在普通屏中其設備像素等于css
像素,但在一些高清屏中,如 Retina 顯示屏,一個css像素對應2
或3
個設備像素,這時顯示出來的元素會變小。為了讓元素如期待顯示,需要傳入原始設計稿尺寸×
倍率的設計稿,根據 DPR 的定義,這樣加載后能夠達到同樣的效果。
尺寸
手機屏幕對角線長度換算成英寸的大小
適配方案
百分比方案
原理
使用 百分比% 定義 寬度,高度 用
px
固定,根據可視區域實時尺寸進行調整,盡可能適應各種分辨率,通常使用max-width
/min-width
控制尺寸范圍過大或者過小。下表是子元素不同屬性設置百分比的依據
屬性 | 設置參考 |
---|---|
height /width
|
基于子元素的直接父元素,width 相對于父元素的width ,height 相對于父元素的height
|
top /bottom 和left /right
|
相對于直接非static 定位的父元素的height /width
|
padding /margin
|
不論是垂直方向或者是水平方向,都相對于直接父親元素的width ,與父元素的height 無關。 |
border-radius |
相對于自身的寬度 |
優勢
原理簡單,不存在兼容性問題
不足
- 如果屏幕尺度跨度太大,相對設計稿過大或者過小的屏幕不能正常顯示,在大屏手機或橫豎屏切換場景下可能會導致頁面元素被拉伸變形,字體大小無法隨屏幕大小發生變化。
...- 設置盒模型的不同屬性時,其百分比設置的參考元素不唯一,容易使布局問題變得復雜
rem方案
原理
rem是相對長度單位,rem方案中的樣式設計為相對于根元素
font-size
計算值的倍數。根據 屏幕寬度 設置html
標簽的font-size
,在布局時使用 rem 單位布局,達到自適應的目的,是 彈性布局 的一種實現方式。
實現過程: 首先獲取文檔根元素和設備
dpr
,設置 rem,在html
文檔加載和解析完成后調整body
字體大小; 在頁面縮放 / 回退 / 前進的時候, 獲取元素的內部寬度 (不包括垂直滾動條,邊框和外邊距),重新調整 rem 大小。
實現方法:用 css 處理器或 npm 包將頁面 css 樣式中的
px
自動轉換成 rem。在整個 flexible 適配方案中,文本使用px
作為單位,使用[data-dpr]
屬性來區分不同dpr
下的文本字號。由于手機瀏覽器對字體顯示最小是8px
,因此對于小尺寸文字需要采用px
為單位,防止通過 rem 轉化后出現顯示問題。手機淘寶 中的字體使用px
為單位,騰訊新聞中的字體使用rem
為單位。
貼上 源碼 分析
(function(win, lib) {
var doc = win.document; //當前文檔對象
var docEl = doc.documentElement; //文檔對象根元素的只讀屬性
var metaEl = doc.querySelector('meta[name="viewport"]');
var flexibleEl = doc.querySelector('meta[name="flexible"]');
var dpr = 0;
var scale = 0;
var tid;
var flexible = lib.flexible || (lib.flexible = {});
if (metaEl) {
//當meta中viewport的標簽設置了scale時,將根據scale手動設置dpr
console.warn('將根據已有的meta標簽來設置縮放比例');
var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
if (match) {
scale = parseFloat(match[1]);
dpr = parseInt(1 / scale);
}
} else if (flexibleEl) {
//當meta中flexible的標簽存在時,據此設置dpr
var content = flexibleEl.getAttribute('content');
if (content) {
var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
if (initialDpr) {
dpr = parseFloat(initialDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
if (maximumDpr) {
dpr = parseFloat(maximumDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
}
}
if (!dpr && !scale) {
//根據js獲取到的devicePixelRatio設置dpr及scale,scale是dpr的倒數
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和3倍方案
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;
}
docEl.setAttribute('data-dpr', dpr);
//文本字號不建議使用rem,flexible適配方案中,文本使用px作為單位,使用[data-dpr]屬性來區分不同dpr下的文本字號
if (!metaEl) {
//添加meta標簽,設置name為viewport,content根據scale設置縮放比(默認、最大、最小縮放比)
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(metaEl);
} else {
var wrap = doc.createElement('div');
wrap.appendChild(metaEl);
doc.write(wrap.innerHTML);
}
}
function refreshRem(){
//更新rem值
var width = docEl.getBoundingClientRect().width;
if (width / dpr > 540) {
width = 540 * dpr;
}
var rem = width / 10; //1rem = viewWidth / 10
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
}
//resize與pageshow延時300ms觸發refreshRem(),使用防抖函數,防止事件被高頻觸發可能引起性能問題
win.addEventListener('resize', function() {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}, false);
win.addEventListener('pageshow', function(e) {
//當一條會話歷史紀錄被執行的時候觸發事件,包括后退/前進按鈕,同時會在onload頁面觸發后初始化頁面時觸發
if (e.persisted) {//表示網頁是否來自緩存
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
}, false);
//在html文檔加載和解析完成后設置body元素字體大小
if (doc.readyState === 'complete') {
doc.body.style.fontSize = 12 * dpr + 'px';
} else {
doc.addEventListener('DOMContentLoaded', function(e) {
doc.body.style.fontSize = 12 * dpr + 'px';
}, false);
}
//瀏覽器有最小字體限制,css在pc上font-size是12px(移動端最小是8px), 也就是css像素是12,其DPR為1,在移動端dpr有可能為2和3,為了保證字體不變小,需要用12*dpr進行換算。
refreshRem();
//實現rem與px相互轉換
flexible.dpr = win.dpr = dpr;
flexible.refreshRem = refreshRem;
flexible.rem2px = function(d) {
var val = parseFloat(d) * this.rem;
if (typeof d === 'string' && d.match(/rem$/)) {
val += 'px';
}
return val;
}
flexible.px2rem = function(d) {
var val = parseFloat(d) / this.rem;
if (typeof d === 'string' && d.match(/px$/)) {
val += 'rem';
}
return val;
}
})(window, window['lib'] || (window['lib'] = {}));
優勢
兼容性好
- ios: 6.1系統以上都支持
- android: 2.1系統以上都支持
-
大部分主流瀏覽器都支持
1.png
- 相較于之前的靜態布局和百分比方案,頁面不會因為伸縮發生變形,自適應效果更佳。
不足
- 不是純css移動適配方案,需要引入js腳本 在頭部內嵌一段
js
腳本 監聽分辨率的變化來動態改變根元素的字體大小,css
樣式和js
代碼有一定 耦合性,并且必須將改變font-size
的代碼放在 css 樣式之前。
...- 小數像素問題,瀏覽器渲染最小的單位是像素,元素根據屏幕寬度自適應,通過 rem 計算后可能會出現小數像素,瀏覽器會對這部分小數四舍五入,按照整數渲染。瀏覽器在渲染時所做的攝入處理只是應用在元素的尺寸渲染上,其真實占據的空間依舊是原始大小。也就是說如果一個元素尺寸是
0.625px
,那么其渲染尺寸應該是1px
,空出的0.375px
空間由其臨近的元素填充;同樣道理,如果一個元素尺寸是0.375px
,其渲染尺寸就應該是0
,但是其會占據臨近元素0.375px
的空間。會導致:縮放到低于1px
的元素時隱時現(解決辦法:指定最小轉換像素,對于比較小的像素,不轉換為 rem 或 vw);兩個同樣寬度的元素因為各自周圍的元素寬度不同,導致兩元素相差1px
;寬高相同的正方形,長寬不等了;border-radius: 50%
畫的圓不圓。
...- Android 瀏覽器下 line-height 垂直居中偏離的問題。常用的垂直居中方式就是使用line-height,這種方法在Android設備下并不能完全居中。
...- cursor: pointer 元素點擊背景變色的問題,對添加了cursor:pointer屬性的元素,在移動端點擊時,背景會高亮。為元素添加
tag-highlight-color:transparent
屬性可以隱藏背景高亮。
vh/vw方案
原理
視口是瀏覽器中用于呈現網頁的區域,移動端的視口通常指的是 布局視口
- vw : 1vw 等于 視口寬度 的 1%
- vh : 1vh 等于 視口高度 的 **1% **
- vmin : 選取 vw 和 vh 中 最小 的那個
- vmax : 選取 vw 和 vh 中 最大 的那個
使用 css 預處理器把設計稿尺寸轉換為 vw 單位,包括 文本,布局高寬,間距 等,使得這些元素能夠隨視口大小自適應調整。以1080px
設計稿為基準,轉化的計算表示為
// 以1080px作為設計稿基準
$vw_base: 1080
@function vw($px) {
@return($px / 1080) * 100vw
}
優勢
- 純 css 移動端適配方案,不存在腳本依賴問題
...- 相對于 rem 以根元素字體大小的倍數 定義 元素大小,邏輯清晰簡單,視口單位依賴于視口的尺寸
"1vw = 1/100 viewport width"
,根據 視口尺寸的百分比 來定義 元素寬度
不足
- 存在一些兼容性問題,Android4.4以下不支持
rem+vw/vh方案
原理
vw/vh 方案能夠實現寬度和高度的自適應,并且邏輯清晰,由于其被支持得較晚,所以存在一定的兼容性問題。將 vw/vh 方案與 rem 方案相結合,給根元素設置隨視口變化的vw單位,可以通過
postcss-plugin-vwtorem
將其轉換。具體的計算過程為:
對于
1080px
寬的設計稿,設置默認根字號的大小為100px
,那么設計稿中1px
對應的是100vw/1080 = 0.0925926vw
,并且1rem = 100px
,也就可以得到1rem = 9.256926vw
同時可以使用媒體查詢限制根元素的最大最小值,實現對頁面的最大最小寬度限制,對用戶的視覺體驗更好。
實用性
rem 彈性布局方式作為移動端web頁面適配方法,后期從 rem 過渡到 vw ,只需要通過 改變根元素大小的計算方式 不需要其他處理。vw 將會成為一種更好的適配方式,目前由于兼容性的原因得不到廣泛應用。rem+vw/vh 不存在 vw/vh 的兼容性問題,可以成為由 rem 向 vw/vh 轉變的一種過渡方案。
基于媒體查詢的響應式設計
響應式設計 使得一個網站同時適配 多種設備 和 多個屏幕,讓網站的布局和功能隨用戶的使用環境(屏幕大小、輸出方式、設備/瀏覽器能力而變化),使其視覺合理,交互方式符合習慣。如使得內容區塊可伸縮與自由排布,邊距適應頁面尺寸,圖片適應比例變化,能夠自動隱藏/部分顯示內容,能自動折疊導航和菜單。
原理
主要實現是通過 媒體查詢,通過給不同分辨率的設備編寫不同的樣式實現響應式布局,用于解決不同設備不同分辨率之間兼容問題,一般是指PC、平板、手機設備之間較大的分辨率差異。實現上不局限于具體的方案,通常結合了 流式布局
+
彈性布局 方案。比如給小屏幕手機設置@2x
圖,為大屏手機設置@3x
圖
@media only screen and (min-width: 375px){
樣式1
}
@media only screen and (min-width: 750){
樣式2
}
優勢
能夠使網頁在不同設備、不同分辨率屏幕上呈現合理布局,不僅僅是樣式伸縮變換
不足
- 要匹配足夠多的設備與屏幕,一個web頁面需要多個設計方案,工作量比較大
...- 通過媒體查詢技術需要設置一定量的斷點,到達某個斷點前后的頁面發生顯著變化,用戶體驗不太友好
移動端web頁面適配方案中的通用問題
1
像素問題
是指設置邊框 為
1px
css像素,在 普通屏幕 下1px
,高清屏幕 (dpr
為2
)下2px
的情況。是由于不同移動設備的dpr
不同,導致1px
css像素,轉換成物理像素后顯示不一樣。
設置scale 為 1/dpr
css 中涉及
1
像素的地方仍然使用px
作為單位,設置<meta>
標簽中initial-scale = 1/dpr
,將整個頁面縮小dpr
倍,對于頁面采用 rem 方案的情況,將頁面的 根字體 再放大dpr
倍,這個時候就能夠在不改變頁面其他布局的情況下,保持邊框的 css 像素為1px
。參考
transform 的 scale 屬性
transform
的scale
屬性允許對元素進行縮放,其中scaleY(y)
通過設置Y軸的值來定義縮放轉換,并結合偽元素使用,通過transform-origin: 50% 0%
修改元素變換的中心點實現。針對橫著的邊框線用scaleY(y)
,針對豎著的邊框線要用scaleX(x)
,針對一圈的邊框線用scale()
,并且需要注意轉移元素變換中心點。
<style>
//針對豎著的邊框線
.className: before {
//其他樣式
transform-origin: 50% 0%;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) { //dpr為2時
.className: before {
transform: scaleY(0.5);
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 3) { //dpr為3時
.className: before {
transform: scaleY(0.33);
}
}
</style>
border-image屬性
使用
border-image
,在元素的邊框上設置一個一半透明一半顯示的圖片。參考
對圖片的處理
加載網頁時,平均
60%
以上的流量來自 加載圖片。指定圖像寬度時使用相對單位,防止意外溢出視口,如width: 50%
,將圖片寬度設置為包含元素寬度的50%
。因為 css 允許內容溢出容器, 需要使用max-width: 100%
來保證圖像及其他內容不會溢出。使用 img 元素的alt
屬性提供描述,描述有助于提高網站的可訪問性,能提供語境給屏幕閱讀器及其他輔助性技術,參考 。維護自適應頁面中圖片寬高比固定比較常用的方法是使用padding
設置。對于不同dpr
以及不同分辨率/尺寸的屏幕,為了避免資源浪費和等待時間延長,需要針對不同的屏幕使用合適的圖片,加載的圖片分為通過標簽引入的圖片和背景圖片。
srcse 和 sizes
對于
<img>
引入的圖片,如果想要圖片適應不同像素密度的屏幕,并且屏幕上顯示圖片的實際尺寸相同,使用srcset
屬性用來指定多張圖像。它的值是一個逗號分隔的字符串,每個部分都是一張圖像的 URL,后面接一個空格,后接是像素密度描述符。瀏覽器根據當前設備的像素密度,選擇需要加載的圖像。如果srcset
屬性都不滿足條件,那么就加載src
屬性指定的默認圖像。
<img srcset="foo-320w.jpg,
foo-480w.jpg 1.5x,
foo-640w.jpg 2x"
src="foo-640w.jpg">
<!--srcset屬性給出了三個圖像URL,適應三種不同的像素密度, 后面的像素密度描述符,格式是像素密度倍數 + 字母x。1x表示單倍像素密度,可以省略。-->
如果想要針對不同屏幕,使用不同分辨率版本和尺寸的圖片,使用屬性
srcse
和sizes
。srcset 定義了允許瀏覽器選擇的圖像集,以及每個圖像的大小(使用w單位)。sizes
定義了一組媒體條件(例如屏幕寬度),指明當某些媒體條件為真時,什么樣的圖片尺寸是最佳選擇。
<img srcset = "elva-fairy-320w.jpg 320w,
elva-fairy-480w.jpg 480w,
elva-fairy-800w.jpg 800w"
sizes = "(max-width: 320px) 280px,
(max-width: 480px) 440px,
800px"
src = "elva-fairy-800w.jpg" alt="Elva dressed as a fairy">
瀏覽器的查詢過程:
- 查看設備寬度;
- 檢查
sizes
列表中哪個媒體條件是第一個為真; - 查看給予該媒體查詢的槽大小;
- 加載
srcset
列表中引用的最接近所選的槽大小的圖像
異步加載
< img> 引入的圖片,使用js自帶的異步加載圖片。根據不同的
dpr
,加載不同分辨率的圖片。
<img id="img" data-src1x="xxx@1x.jpg" data-src2x="xxx@2x.jpg" data-src3x="xxx@3x.jpg"/>
var dpr = window.devicePixelRatio;
if(dpr > 3){
dpr = 3;
};
var imgSrc = $('#img').data('src'+dpr+'x');
var img = new Image();
img.src = imgSrc;
img.onload = function(imgObj){
$('#img').remove().prepend(imgObj);//替換img對象
};
picture
為不同的視口提供不同的圖片,使用
<picture>
標簽。<picture>
是html5
中定義的一個容器標簽,內部使用<source>
和<image>
,瀏覽器會匹配<source>
的type
,media
,srcset
等屬性,找到最適合當前布局 / 視口寬度 / 設備像素密度的圖像進行加載。這里的<img>
標簽是瀏覽器不支持picture
元素,或者支持picture
但沒有合適的媒體定義時的后備,不能省略。
<picture>
<source media="(min-width: 30px)" srcset="cat-vertical.jpg">
<source media="(min-width: 60px)" srcset="cat-horizontal.jpg">
<img src="cat.jpg" alt="cat">
</picture>
Image-set
對于背景圖片,使用
image-set
根據用戶設備的分辨率匹配合適的圖像, 同時要考慮兼容性問題。
<style>
.css {
background-image: url(1x.png); /*不支持image-set的情況下顯示*/
background: -image-set(
url(1x.png) 1x,/* 支持image-set的瀏覽器的[普通屏幕]下 */
url(2x.png) 2x,/* 支持image-set的瀏覽器的[2倍Retina屏幕] */
url(3x.png) 3x/* 支持image-set的瀏覽器的[3倍Retina屏幕] */
);
}
</style>
media query
對于背景圖片,使用媒體查詢自動切換不同分辨率的版本
<style>
/* 普通顯示屏(設備像素比例小于等于1)使用1倍的圖 */
.css{
background-image: url(img_1x.png);
}
/* 高清顯示屏(設備像素比例大于等于2)使用2倍圖 */
@media only screen and (min-device-pixel-ratio:2){
.css{
background-image: url(img_2x.png);
}
}
/* 高清顯示屏(設備像素比例大于等于3)使用3倍圖 */
@media only screen and (min-device-pixel-ratio:3){
.css{
background-image: url(img_3x.png);
}
}
</style>
總結
對于上述的各種移動端web頁面自適應方案來說,都存在著一些優勢和不足。對于國內的一些互聯網站,通過查看網頁源代碼發現,它可能不是某一種方案的單獨使用,而是幾種方案的結合。一個頁面上,元素的寬度設置上有百分比,也有
rem
,字體的樣式中有rem
,有em
,也有固定大小的px
;在屏幕寬度過大時不再縮放,也會用到媒體查詢,并且響應式設計更多地可能是針對不同設備間的自適應。對于移動端web頁面的自適應方案來說,現在用的比較多的是rem
,逐漸向vw/vh
發展,而rem+vw/vh
則是作為vw/vh
向后兼容的一種過渡。