移動端Web頁面適配方案(整理版)

@(概述)[基本概念|百分比|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像素對應的物理像素具數不同。標準的顯示密度下,1css像素對應一個物理像素,縮放時,1css像素對應的物理像素會減增。是一種設備獨立像素(device independent pixels: DIPs)

PPI (pixel per inch)

像素密度,每英寸所擁有的像素數。值越高,顯示畫面細節越豐富。計算公式為:\frac{\sqrt{(W^2+H^2)}}{S},其中 WH 是分辨率的寬高,S 是屏幕尺寸。

DPI (dot per inch)

打印設備每英寸印刷出來的點有多少個,值越高,圖片越細膩。

DPR (devicePixelRatio)

設備物理像素和設備獨立像素比,即DPR =\frac{物理像素}{css像素}是指在理想布局寬度,使用多少個物理像素來渲染一個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像素對應23個設備像素,這時顯示出來的元素會變小。為了讓元素如期待顯示,需要傳入原始設計稿尺寸×倍率的設計稿,根據 DPR 的定義,這樣加載后能夠達到同樣的效果。

尺寸

手機屏幕對角線長度換算成英寸的大小

適配方案

百分比方案

原理

使用 百分比% 定義 寬度高度px固定,根據可視區域實時尺寸進行調整,盡可能適應各種分辨率,通常使用max-width/min-width控制尺寸范圍過大或者過小。下表是子元素不同屬性設置百分比的依據

屬性 設置參考
height/width 基于子元素的直接父元素,width相對于父元素的widthheight相對于父元素的height
top/bottomleft/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的元素時隱時現(解決辦法:指定最小轉換像素,對于比較小的像素,不轉換為 remvw);兩個同樣寬度的元素因為各自周圍的元素寬度不同,導致兩元素相差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 : 選取 vwvh最小 的那個
  • vmax : 選取 vwvh最大 的那個

使用 css 預處理器把設計稿尺寸轉換為 vw 單位,包括 文本布局高寬間距 等,使得這些元素能夠隨視口大小自適應調整。以1080px設計稿為基準,轉化的計算表示為

// 以1080px作為設計稿基準
$vw_base: 1080
@function vw($px) {
    @return($px / 1080) * 100vw
}

優勢

  • css 移動端適配方案,不存在腳本依賴問題
    ...
  • 相對于 rem根元素字體大小的倍數 定義 元素大小,邏輯清晰簡單,視口單位依賴于視口的尺寸 "1vw = 1/100 viewport width",根據 視口尺寸的百分比 來定義 元素寬度

不足

  • 存在一些兼容性問題,Android4.4以下不支持
2.png

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 的兼容性問題,可以成為由 remvw/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高清屏幕 (dpr2)下2px的情況。是由于不同移動設備的dpr不同,導致1px css像素,轉換成物理像素后顯示不一樣。

設置scale 為 1/dpr

css 中涉及1像素的地方仍然使用px作為單位,設置<meta> 標簽中 initial-scale = 1/dpr ,將整個頁面縮小dpr倍,對于頁面采用 rem 方案的情況,將頁面的 根字體 再放大dpr倍,這個時候就能夠在不改變頁面其他布局的情況下,保持邊框的 css 像素為1px參考

transform 的 scale 屬性

transformscale屬性允許對元素進行縮放,其中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表示單倍像素密度,可以省略。-->

如果想要針對不同屏幕,使用不同分辨率版本和尺寸的圖片,使用屬性srcsesizessrcset 定義了允許瀏覽器選擇的圖像集,以及每個圖像的大小(使用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向后兼容的一種過渡。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,739評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,634評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,653評論 0 377
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,063評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,835評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,235評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,315評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,459評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,000評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,819評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,004評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,560評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,257評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,676評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,937評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,717評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,003評論 2 374

推薦閱讀更多精彩內容

  • 移動端適配方案:1)viewport(scale=1/dpr)2)rem3)flex4)vm/vh一、什么是移動端...
    puxiaotaoc閱讀 43,101評論 3 56
  • 剛開始做移動端web開發的同學應該都碰到過頁面適配問題,為什么我在開發手機上調試好的頁面在其他手機會有這樣或那樣的...
    留七七閱讀 19,445評論 5 80
  • 適配 在不同尺寸的移動設備上, 頁面相對性的達到合理的展示(自適應), 或者保持同一效果的等比縮放(看起來差不多)...
    Veycn閱讀 1,649評論 0 0
  • 本文介紹了移動端適配的3種方法,以及移動端圖片模糊問題和1px細線問題的解決方法。當然了,在這之前先整理了與這些方...
  • 偶然看到這樣一個平臺,想著多年來寫的東西正好整理出來放在這上面挺好,沒事自己看看,別人也能評價看看,寫東西是我一直...
    塵世淡漠閱讀 586評論 1 6