vue 項(xiàng)目中的自適應(yīng)布局


前端頁(yè)面開(kāi)發(fā)持痰,要適配不同分辨率的屏幕灶搜,一般主流自適應(yīng)方法有 %,vm/vh,rem割卖,媒體查詢前酿。

1. px 與 視口
2. %
3. 媒體查詢
4. rem
5. vm/vh

一. px 與視口

在靜態(tài)頁(yè)面中,通常使用px(像素)作為盒子容器寬高的單位鹏溯,在pc端罢维,通常認(rèn)為css中,1px所表示的真實(shí)長(zhǎng)度是固定的。

那么丙挽,px真的是一個(gè)設(shè)備無(wú)關(guān)言津,跟長(zhǎng)度單位米和分米一樣是固定大小的嗎?

答案是否定的取试,pc端下和移動(dòng)端下我們?cè)O(shè)置的font-size統(tǒng)一為16px悬槽。

可以看出,字體都是16px瞬浓,顯然在pc端中文字正常顯示初婆,而在移動(dòng)端文字很小,幾乎看不到猿棉,說(shuō)明在css中1px并不是固定大小磅叛,直觀從我們發(fā)現(xiàn)在移動(dòng)端1px所表示的長(zhǎng)度較小,所以導(dǎo)致文字顯示不清楚萨赁。

那么css中的1px的真實(shí)長(zhǎng)度到底由什么決定呢弊琴?
為了理清楚這個(gè)概念我們首先介紹像素和視口的概念。

1.像素

像素是網(wǎng)頁(yè)布局的基礎(chǔ)杖爽,一個(gè)像素表示了計(jì)算機(jī)屏幕所能顯示的最小區(qū)域敲董,像素分為兩種類型:css像素和物理像素。

我們?cè)趈s或者css代碼中使用的px單位就是指的是css像素慰安,物理像素也稱設(shè)備像素腋寨,只與設(shè)備或者說(shuō)硬件有關(guān),同樣尺寸的屏幕化焕,設(shè)備的密度越高萄窜,物理像素也就越多。下表表示css像素和物理像素的具體區(qū)別:

css像素: 為web開(kāi)發(fā)者提供撒桨,在css中使用的一個(gè)抽象單位

物理像素: 只與設(shè)備的硬件密度有關(guān)查刻,任何設(shè)備的物理像素都是固定的

那么css像素與物理像素的轉(zhuǎn)換關(guān)系是怎么樣的呢?
為了明確css像素和物理像素的轉(zhuǎn)換關(guān)系凤类,必須先了解視口是什么穗泵。

2.視口

廣義的視口,是指瀏覽器顯示內(nèi)容的屏幕區(qū)域踱蠢,狹義的視口包括了布局視口火欧、視覺(jué)視口和理想視口

(1) 布局視口(layout viewport)

布局視口定義了pc網(wǎng)頁(yè)在移動(dòng)端的默認(rèn)布局行為,因?yàn)橥ǔc的分辨率較大茎截,布局視口默認(rèn)為980px苇侵。
也就是說(shuō)在不設(shè)置網(wǎng)頁(yè)的viewport的情況下,pc端的網(wǎng)頁(yè)默認(rèn)會(huì)以布局視口為基準(zhǔn)企锌,在移動(dòng)端進(jìn)行展示榆浓。因此我們可以明顯看出來(lái),默認(rèn)為布局視口時(shí)撕攒,根植于pc端的網(wǎng)頁(yè)在移動(dòng)端展示很模糊陡鹃。

(2) 視覺(jué)視口(visual viewport)

視覺(jué)視口表示瀏覽器內(nèi)看到的網(wǎng)站的顯示區(qū)域,用戶可以通過(guò)縮放來(lái)查看網(wǎng)頁(yè)的顯示內(nèi)容抖坪,從而改變視覺(jué)視口萍鲸。視覺(jué)視口的定義,就像拿著一個(gè)放大鏡分別從不同距離觀察同一個(gè)物體擦俐,視覺(jué)視口僅僅類似于放大鏡中顯示的內(nèi)容脊阴,因此視覺(jué)視口不會(huì)影響布局視口的寬度和高度。

(3) 理想視口(ideal viewport)

理想視口或者應(yīng)該全稱為“理想的布局視口”蚯瞧,在移動(dòng)設(shè)備中就是指設(shè)備的分辨率嘿期。
換句話說(shuō),理想視口或者說(shuō)分辨率就是給定設(shè)備物理像素的情況下埋合,最佳的“布局視口”备徐。

上述視口中,最重要的是要明確理想視口的概念甚颂,在移動(dòng)端中蜜猾,理想視口或者說(shuō)分辨率跟物理像素之間有什么關(guān)系呢?
為了理清分辨率和物理像素之間的聯(lián)系振诬,我們介紹一個(gè)用DPR(Device pixel ratio)設(shè)備像素比來(lái)表示瓣铣,則可以寫成:

1 DPR = 物理像素/分辨率

在不縮放的情況下,一個(gè)css像素就對(duì)應(yīng)一個(gè)dpr贷揽,也就是說(shuō)棠笑,在不縮放

1 CSS像素 = 物理像素/分辨率

此外,在移動(dòng)端的布局中禽绪,我們可以通過(guò)viewport元標(biāo)簽來(lái)控制布局蓖救,比如一般情況下,我們可以通過(guò)下述標(biāo)簽使得移動(dòng)端在理想視口下布局:

<meta id="viewport" name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1; user-scalable=no;">

上述meta標(biāo)簽的每一個(gè)屬性的詳細(xì)介紹如下:

其中我們來(lái)看width屬性印屁,在移動(dòng)端布局時(shí)循捺,在meta標(biāo)簽中我們會(huì)將width設(shè)置稱為device-width,device-width一般是表示分辨率的寬雄人,通過(guò)width=device-width的設(shè)置我們就將布局視口設(shè)置成了理想的視口从橘。

3.px與自適應(yīng)

上述我們了解到了當(dāng)通過(guò)viewport元標(biāo)簽念赶,設(shè)置布局視口為理想視口時(shí),1個(gè)css像素可以表示成:

1 CSS像素 = 物理像素/分辨率

我們直到恰力,在pc端的布局視口通常情況下為980px叉谜,移動(dòng)端以iphone6為例,分辨率為375 * 667
也就是說(shuō)布局視口在理想的情況下為375px踩萎。比如現(xiàn)在我們有一個(gè)750px * 1134px的視覺(jué)稿停局,那么在pc端,一個(gè)css像素可以如下計(jì)算:

PC端: 1 CSS像素 = 物理像素/分辨率 = 750 / 980 =0.76 px

而在iphone6下:

iphone6:1 CSS像素 = 物理像素 /分辨率 = 750 / 375 = 2 px

也就是說(shuō)在PC端香府,一個(gè)CSS像素可以用0.76個(gè)物理像素來(lái)表示董栽,而iphone6中 一個(gè)CSS像素表示了2個(gè)物理像素。

此外不同的移動(dòng)設(shè)備分辨率不同企孩,也就是1個(gè)CSS像素可以表示的物理像素是不同的锭碳,因此如果在css中僅僅通過(guò)px作為長(zhǎng)度和寬度的單位,造成的結(jié)果就是無(wú)法通過(guò)一套樣式勿璃,實(shí)現(xiàn)各端的自適應(yīng)

二工禾、媒體查詢

在前面我們說(shuō)到,不同端的設(shè)備下蝗柔,在css文件中闻葵,1px所表示的物理像素的大小是不同的,因此通過(guò)一套樣式癣丧,是無(wú)法實(shí)現(xiàn)各端的自適應(yīng)槽畔。由此我們聯(lián)想:

如果一套樣式不行,那么能否給每一種設(shè)備各一套不同的樣式來(lái)實(shí)現(xiàn)自適應(yīng)的效果胁编?
答案是肯定的厢钧。

使用@media媒體查詢可以針對(duì)不同的媒體類型定義不同的樣式,特別是響應(yīng)式頁(yè)面嬉橙,可以針對(duì)不同屏幕的大小早直,編寫多套樣式,從而達(dá)到自適應(yīng)的效果市框。舉例來(lái)說(shuō):

@media screen and (max-width: 960px){
    body{
      background-color:#FF6699
    }
}

@media screen and (max-width: 768px){
    body{
      background-color:#00FF66;
    }
}

@media screen and (max-width: 550px){
    body{
      background-color:#6633FF;
    }
}

@media screen and (max-width: 320px){
    body{
      background-color:#FFFF00;
    }
}

上述的代碼通過(guò)媒體查詢定義了幾套樣式霞扬,通過(guò)max-width設(shè)置樣式生效時(shí)的最大分辨率,上述的代碼分別對(duì)分辨率在0~320px枫振,320px~550px喻圃,550px~768px以及768px~960px的屏幕設(shè)置了不同的背景顏色。

通過(guò)媒體查詢粪滤,可以通過(guò)給不同分辨率的設(shè)備編寫不同的樣式來(lái)實(shí)現(xiàn)響應(yīng)式的布局斧拍,比如我們?yōu)椴煌直媛实钠聊唬O(shè)置不同的背景圖片杖小。比如給小屏幕手機(jī)設(shè)置@2x圖肆汹,為大屏幕手機(jī)設(shè)置@3x圖愚墓,通過(guò)媒體查詢就能很方便的實(shí)現(xiàn)。

但是媒體查詢的缺點(diǎn)也很明顯昂勉,如果在瀏覽器大小改變時(shí)浪册,需要改變的樣式太多,那么多套樣式代碼會(huì)很繁瑣硼啤。

三议经、百分比

除了用px結(jié)合媒體查詢實(shí)現(xiàn)響應(yīng)式布局外斧账,我們也可以通過(guò)百分比單位 " % " 來(lái)實(shí)現(xiàn)響應(yīng)式的效果谴返。

比如當(dāng)瀏覽器的寬度或者高度發(fā)生變化時(shí),通過(guò)百分比單位咧织,通過(guò)百分比單位可以使得瀏覽器中的組件的寬和高隨著瀏覽器的變化而變化嗓袱,從而實(shí)現(xiàn)響應(yīng)式的效果。

為了了解百分比布局习绢,首先要了解的問(wèn)題是:
css中的子元素中的百分比(%)到底是誰(shuí)的百分比渠抹?

直觀的理解,我們可能會(huì)認(rèn)為子元素的百分比完全相對(duì)于直接父元素闪萄,height百分比相對(duì)于height梧却,width百分比相對(duì)于width。
當(dāng)然這種理解是正確的败去,但是根據(jù)css的盒式模型放航,除了height、width屬性外圆裕,還具有padding广鳍、border、margin等等屬性吓妆。

那么這些屬性設(shè)置成百分比赊时,是根據(jù)父元素的那些屬性呢?
此外還有border-radius和translate等屬性中的百分比行拢,又是相對(duì)于什么呢祖秒?
下面來(lái)具體分析。

1. 百分比的具體分析

(1)子元素height和width的百分比

子元素的height或width中使用百分比舟奠,是相對(duì)于子元素的直接父元素狈涮,width相對(duì)于父元素的width,height相對(duì)于父元素的height鸭栖。比如:

<div class="parent">
  <div class="child"></div>
</div>

(2) top和bottom 平痰、left和right
子元素的top和bottom如果設(shè)置百分比,則相對(duì)于直接非static定位(默認(rèn)定位)的父元素的高度彤路,
同樣子元素的left和right如果設(shè)置百分比,則相對(duì)于直接非static定位(默認(rèn)定位的)父元素的寬度暴浦。

(3)padding
子元素的padding如果設(shè)置百分比,不論是垂直方向或者是水平方向晓锻,都相對(duì)于直接父親元素的width歌焦,而與父元素的height無(wú)關(guān)。
舉例來(lái)說(shuō):

.parent{
  width:200px;
  height:100px;
  background:green;
}
.child{
  width:0px;
  height:0px;
  background:blue;
  color:white;
  padding-top:50%;
  padding-left:50%;
}

子元素的初始寬高為0砚哆,通過(guò)padding可以將父元素?fù)未蠖榔玻蠄D的藍(lán)色部分是一個(gè)正方形,且邊長(zhǎng)為100px,說(shuō)明padding不論寬高躁锁,如果設(shè)置成百分比都相對(duì)于父元素的width纷铣。

(4)margin
跟padding一樣,margin也是如此战转,子元素的margin如果設(shè)置成百分比搜立,不論是垂直方向還是水平方向,都相對(duì)于直接父元素的width槐秧。這里就不具體舉例啄踊。

(5)border-radius
border-radius不一樣,如果設(shè)置border-radius為百分比刁标,則是相對(duì)于自身的寬度颠通,舉例來(lái)說(shuō):

<div class="trangle"></div>
<!--設(shè)置border-radius為百分比:-->
.trangle{
  width:100px;
  height:100px;
  border-radius:50%;
  background:blue;
  margin-top:10px;
}

除了border-radius外,還有比如translate膀懈、background-size等都是相對(duì)于自身的顿锰,這里就不一一舉例。

2. 百分比單位布局應(yīng)用

百分比單位在布局上應(yīng)用還是很廣泛的吏砂,這里介紹一種應(yīng)用撵儿。
比如我們要實(shí)現(xiàn)一個(gè)固定長(zhǎng)寬比的長(zhǎng)方形,比如要實(shí)現(xiàn)一個(gè)長(zhǎng)寬比為4:3的長(zhǎng)方形,我們可以根據(jù)padding屬性來(lái)實(shí)現(xiàn)狐血,因?yàn)閜adding不管是垂直方向還是水平方向淀歇,百分比單位都相對(duì)于父元素的寬度,因此我們可以設(shè)置padding-top為百分比來(lái)實(shí)現(xiàn)匈织,長(zhǎng)寬自適應(yīng)的長(zhǎng)方形:

<div class="trangle"></div>
<!--設(shè)置樣式讓其自適應(yīng):-->
.trangle{
  height:0;
  width:100%;
  padding-top:75%;
}

通過(guò)設(shè)置padding-top:75%,相對(duì)比寬度的75%浪默,因此這樣就設(shè)置了一個(gè)長(zhǎng)寬高恒定比例的長(zhǎng)方形.

3. 百分比單位缺點(diǎn)

從上述對(duì)于百分比單位的介紹我們很容易看出如果全部使用百分比單位來(lái)實(shí)現(xiàn)響應(yīng)式的布局,有明顯的以下兩個(gè)缺點(diǎn):

(1)計(jì)算困難缀匕,如果我們要定義一個(gè)元素的寬度和高度纳决,按照設(shè)計(jì)稿,必須換算成百分比單位乡小。

(2)從小節(jié)1可以看出阔加,各個(gè)屬性中如果使用百分比,相對(duì)父元素的屬性并不是唯一的满钟。 比如width和height相對(duì)于父元素的width和height胜榔,而margin胳喷、
     padding不管垂直還是水平方向都相對(duì)比父元素的寬度、border-radius則是相對(duì)于元素自身等等夭织, 造成我們使用百分比單位容易使布局問(wèn)題變得復(fù)雜

四吭露、自適應(yīng)場(chǎng)景下的rem解決方案

1. rem單位

首先來(lái)看,什么是rem單位尊惰。rem是一個(gè)靈活的讲竿、可擴(kuò)展的單位,由瀏覽器轉(zhuǎn)化像素并顯示弄屡。與em單位不同题禀,rem單位無(wú)論嵌套層級(jí)如何,都只相對(duì)于瀏覽器的根元素(HTML元素)的font-size琢岩。默認(rèn)情況下投剥,html元素的font-size為12px师脂,所以:

1 rem = 12px

為了計(jì)算方便担孔,通常可以將html的font-size設(shè)置成:

html{ font-size: 67.5% }

這種情況下:

1 rem = 10px
2.通過(guò)rem來(lái)實(shí)現(xiàn)響應(yīng)式布局

rem單位都是相對(duì)于根元素html的font-size來(lái)決定大小的,根元素的font-size相當(dāng)于提供了一個(gè)基準(zhǔn)吃警,當(dāng)頁(yè)面的size發(fā)生變化時(shí)糕篇,只需要改變font-size的值,那么以rem為固定單位的元素的大小也會(huì)發(fā)生響應(yīng)的變化酌心。

因此拌消,如果通過(guò)rem來(lái)實(shí)現(xiàn)響應(yīng)式的布局,只需要根據(jù)視圖容器的大小安券,動(dòng)態(tài)的改變font-size即可墩崩。

function refreshRem() {
    var docEl = doc.documentElement;
    var width = docEl.getBoundingClientRect().width;
    var rem = width / 10;
    docEl.style.fontSize = rem + 'px';
    flexible.rem = win.rem = rem;
}
win.addEventListener('resize', refreshRem);

上述代碼中將視圖容器分為10份,font-size用十分之一的寬度來(lái)表示侯勉,最后在header標(biāo)簽中執(zhí)行這段代碼鹦筹,就可以動(dòng)態(tài)定義font-size的大小,從而1rem在不同的視覺(jué)容器中表示不同的大小址貌,用rem固定單位可以實(shí)現(xiàn)不同容器內(nèi)布局的自適應(yīng)铐拐。

3. rem2px和px2rem

如果在響應(yīng)式布局中使用rem單位,那么存在一個(gè)單位換算的問(wèn)題练对,rem2px表示從rem換算成px遍蟋,這個(gè)就不說(shuō)了,只要rem乘以相應(yīng)的font-size中的大小螟凭,就能換算成px虚青。更多的應(yīng)用是px2rem,表示的是從px轉(zhuǎn)化為rem螺男。

比如給定的視覺(jué)稿為750px(物理像素)棒厘,如果我們要將所有的布局單位都用rem來(lái)表示

一種比較笨的辦法就是對(duì)所有的height和width等元素钟些,乘以相應(yīng)的比例,現(xiàn)將視覺(jué)稿換算成rem單位绊谭,然后一個(gè)個(gè)的用rem來(lái)表示政恍。

另一種比較方便的解決方法就是,在css中我們還是用px來(lái)表示元素的大小达传,最后編寫完css代碼之后篙耗,將css文件中的所有px單位,轉(zhuǎn)化成rem單位宪赶。

px2rem的原理也很簡(jiǎn)單宗弯,重點(diǎn)在于預(yù)處理以px為單位的css文件,處理后將所有的px變成rem單位搂妻∶杀#可以通過(guò)兩種方式來(lái)實(shí)現(xiàn):

<!--1) webpack loader的形式:-->

npm install px2rem-loader

<!--在webpack的配置文件中:-->

module.exports = {
  // ...
  module: {
    rules: [{
      test: /\.css$/,
      use: [{
        loader: 'style-loader'
      }, {
        loader: 'css-loader'
      }, {
        loader: 'px2rem-loader',
        // options here
        options: {
          remUni: 75,
          remPrecision: 8
        }
      }]
    }]
  }
}

<!--2)webpack中使用postcss plugin-->

npm install postcss-loader

<!--在webpack的plugin中:-->

var px2rem = require('postcss-px2rem');

module.exports = {
  module: {
    loaders: [
      {
        test: /\.css$/,
        loader: "style-loader!css-loader!postcss-loader"
      }
    ]
  },
  postcss: function() {
    return [px2rem({remUnit: 75})];
  }
}
4.vue 中的 rem 布局

1)vue2 中

1. Vue-cli2.x中的用法

    1)下載lib-flexible

npm i lib-flexible --save

    2)引入lib-flexible

<!--在main.js中引入lib-flexible-->
import 'lib-flexible/flexible'

    3)設(shè)置meta標(biāo)簽

<!--通過(guò)meta標(biāo)簽,設(shè)置設(shè)備寬度以及縮放比例-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">

    4)安裝px2rem-loader

npm install px2rem-loader --save-dev

    5)配置px2rem-loader

<!--在build文件中找到util.js欲主,將px2rem-loader添加到cssLoaders中-->
const cssLoader = {
    loader: 'css-loader',
    options: {
      minimize: process.env.NODE_ENV === 'production',
      sourceMap: options.sourceMap
    }
}
const px2remLoader = {
    loader: 'px2rem-loader',
    options: {
      remUnit: 75
    }
}

<!--在generateLoaders方法中添加px2remLoader-->

// generate loader string to be used with extract text plugin

  function generateLoaders (loader, loaderOptions) {
// const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]

var loaders = [cssLoader,px2remLoader]

if (loader) {
  loaders.push({
    loader: loader + '-loader',
    options: Object.assign({}, loaderOptions, {
      sourceMap: options.sourceMap
    })
  })
}

2)vue3 中的用法


    lib-flexible:讓網(wǎng)頁(yè)根據(jù)設(shè)備dpr和寬度邓厕,利用viewport和html根元素的font-size配合rem來(lái)適配不同尺寸的移動(dòng)端設(shè)備 

    1)安裝lib-flexible

yarn add lib-flexible 

    2)引入lib-flexible

<!--在main.js中引入lib-flexible-->
import 'lib-flexible/flexible'

pxtorem:將項(xiàng)目中css的px轉(zhuǎn)成rem單位,免去計(jì)算煩惱 
1)安裝postcss-pxtorem 

yarn add postcss-pxtorem 

2) 配置postcss-pxtorem 

<!--package.json內(nèi)扁瓢,在postcss內(nèi)添加-->
"postcss": {
    "plugins": {
      "autoprefixer": {},
      "postcss-pxtorem": {
        "rootValue": 75 // 設(shè)計(jì)稿寬度的1/10,
        "propList":['*'],
        // 需要做轉(zhuǎn)化處理的屬性详恼,如`hight`、`width`引几、`margin`等昧互,`*`表示全部
     }
    }
  }
  
TIPS
1、pxtorem中伟桅,對(duì)于想忽略的px寫成大寫即可敞掘,諸如 border:1PX solid #fff;
2、也可以選擇postcss-px2rem楣铁,我更喜歡pxtorem的忽略方式玖雁,方便我vscode的beautify自動(dòng)格式化代碼
3、postcss-pxtorem 與 px2rem-loader的更多比較見(jiàn):[postcss自學(xué)筆記(二)][7]
5. rem 布局的缺點(diǎn)

通過(guò)rem單位民褂,可以實(shí)現(xiàn)響應(yīng)式的布局茄菊,特別是引入相應(yīng)的postcss相關(guān)插件,免去了設(shè)計(jì)稿中的px到rem的計(jì)算赊堪。
rem單位在國(guó)外的一些網(wǎng)站也有使用面殖,這里所說(shuō)的rem來(lái)實(shí)現(xiàn)布局的缺點(diǎn),或者說(shuō)是小缺陷是:

在響應(yīng)式布局中哭廉,必須通過(guò)js來(lái)動(dòng)態(tài)控制根元素font-size的大小脊僚。
也就是說(shuō)css樣式和js代碼有一定的耦合性。且必須將改變font-size的代碼放在css樣式之前

五. 通過(guò)vw/vh來(lái)實(shí)現(xiàn)自適應(yīng)

1. 什么是vw/vh ?

css3中引入了一個(gè)新的單位vw/vh,與視圖窗口有關(guān)辽幌,vw表示相對(duì)于視圖窗口的寬度增淹,vh表示相對(duì)于視圖窗口高度,除了vw和vh外乌企,還有vmin和vmax兩個(gè)相關(guān)的單位虑润。各個(gè)單位具體的含義如下:

這里我們發(fā)現(xiàn)視窗寬高都是100vw/100vh,那么vw或者vh加酵,下簡(jiǎn)稱vw拳喻,很類似百分比單位。vw和%的區(qū)別為:

從對(duì)比中我們可以發(fā)現(xiàn)猪腕,vw單位與百分比類似冗澈,單確有區(qū)別,前面我們介紹了百分比單位的換算困難陋葡,這里的vw更像"理想的百分比單位"亚亲。

任意層級(jí)元素,在使用vw單位的情況下腐缤,1vw都等于視圖寬度的百分之一捌归。
2. vw單位換算

同樣的,如果要將px換算成vw單位柴梆,很簡(jiǎn)單陨溅,只要確定視圖的窗口大兄栈蟆(布局視口)绍在,如果我們將布局視口設(shè)置成分辨率大小,比如對(duì)于iphone6/7 375*667的分辨率雹有,那么px可以通過(guò)如下方式換算成vw:

  1px = (1/375)*100 vw

此外偿渡,也可以通過(guò)postcss的相應(yīng)插件,預(yù)處理css做一個(gè)自動(dòng)的轉(zhuǎn)換霸奕,postcss-px-to-viewport可以自動(dòng)將px轉(zhuǎn)化成vw溜宽。 postcss-px-to-viewport的默認(rèn)參數(shù)為:

var defaults = {
  viewportWidth: 320,
  viewportHeight: 568, 
  unitPrecision: 5,
  viewportUnit: 'vw',
  selectorBlackList: [],
  minPixelValue: 1,
  mediaQuery: false
};

通過(guò)指定視窗的寬度和高度,以及換算精度质帅,就能將px轉(zhuǎn)化成vw适揉。

3. vw/vh單位的兼容性

可以在https://caniuse.com/ 查看各個(gè)版本的瀏覽器對(duì)vw單位的支持性。

從上圖我們發(fā)現(xiàn)煤惩,絕大多數(shù)的瀏覽器支持vw單位嫉嘀。
4. vh 下載插件 postcss-viewport-units 時(shí),使用使用偽類選擇器遇到的問(wèn)題
<!--在 .postcssrc.js 里配置-->
module.exports = {
  "plugins": {
    "postcss-import": {},
    "postcss-url": {},
    // to edit target browsers: use "browserslist" field in package.json
    // "autoprefixer": {},
      "postcss-aspect-ratio-mini": {},
      "postcss-write-svg": {
          utf8: false
      },
      "postcss-cssnext": {},
      "postcss-px-to-viewport": {
        // 視窗的寬度魄揉,對(duì)應(yīng)的是我們?cè)O(shè)計(jì)稿的寬度剪侮,移動(dòng)端一般是750,如果是pc端那就是類似1920這樣的尺寸
          viewportWidth: 1920,
          viewportHeight: 1080,    // 視窗的高度洛退,也可以不配置
          unitPrecision: 3,       // 指定`px`轉(zhuǎn)換為視窗單位值的小數(shù)位數(shù)(很多時(shí)候無(wú)法整除)
          viewportUnit: 'vw',    // 指定需要轉(zhuǎn)換成的視窗單位瓣俯,建議使用vw
          // 過(guò)濾掉不轉(zhuǎn)換為視窗單位的class類名杰标,可以自定義,可以無(wú)限添加,建議定義一至兩個(gè)通用的類名
          selectorBlackList: ['.ignore', '.hairlines'],  
          minPixelValue: 1,      // 小于或等于`1px`不轉(zhuǎn)換為視窗單位彩匕,你也可以設(shè)置為你想要的值
          mediaQuery: false      // 允許在媒體查詢中轉(zhuǎn)換`px`
      },
      <!--postcss-viewport-units":{} 官方建議-->"
      <!--過(guò)濾掉::after ::before 的配置-->
      "postcss-viewport-units":{
          filterRule: rule => rule.selector.indexOf('::after') === -1 &&
          rule.selector.indexOf('::before') === -1 &&
          rule.selector.indexOf(':after') === -1 &&
          rule.selector.indexOf(':before') === -1
      },
      "cssnano": {
          preset: "default", // 設(shè)置成default將不會(huì)啟用autoprefixer
          "postcss-zindex": false
      }
  }
}
  1. vh 使用
// 命令行輸入:
npm install postcss-px-to-viewport --save
npm install lib-flexible --save

package.json 里添加

  "postcss": {
        "plugins": {
            "autoprefixer": {},
            "postcss-px-to-viewport": {
                "viewportWidth": 750,
                "minPixelValue": 1
            }
        }
    },

原因可以看圖:

因?yàn)槭褂?vh 后腔剂,會(huì)給每個(gè)普通div標(biāo)簽加上 content 屬性,但是如果在偽類選擇器上加上 content 驼仪,會(huì)顯示出來(lái)桶蝎,設(shè)置過(guò)濾函數(shù)會(huì)規(guī)避掉::after ::before等。

綜上所述谅畅,使用 vw/vh 布局實(shí)現(xiàn)自適應(yīng)優(yōu)于其他方案登渣,能夠完美的解決調(diào)屏幕自適應(yīng)問(wèn)題
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市毡泻,隨后出現(xiàn)的幾起案子胜茧,更是在濱河造成了極大的恐慌,老刑警劉巖仇味,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呻顽,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡丹墨,警方通過(guò)查閱死者的電腦和手機(jī)廊遍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)贩挣,“玉大人喉前,你說(shuō)我怎么就攤上這事⊥醪疲” “怎么了卵迂?”我有些...
    開(kāi)封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)绒净。 經(jīng)常有香客問(wèn)我见咒,道長(zhǎng),這世上最難降的妖魔是什么挂疆? 我笑而不...
    開(kāi)封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任改览,我火速辦了婚禮,結(jié)果婚禮上缤言,老公的妹妹穿的比我還像新娘宝当。我一直安慰自己,他們只是感情好墨闲,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布今妄。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪盾鳞。 梳的紋絲不亂的頭發(fā)上犬性,一...
    開(kāi)封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音腾仅,去河邊找鬼乒裆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛推励,可吹牛的內(nèi)容都是我干的鹤耍。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼验辞,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼稿黄!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起跌造,我...
    開(kāi)封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤杆怕,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后壳贪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體陵珍,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年违施,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了互纯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡磕蒲,死狀恐怖留潦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情亿卤,我是刑警寧澤愤兵,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站排吴,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏懦鼠。R本人自食惡果不足惜钻哩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肛冶。 院中可真熱鬧街氢,春花似錦、人聲如沸睦袖。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至伦乔,卻和暖如春厉亏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背烈和。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工爱只, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人招刹。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓恬试,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親疯暑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子训柴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容