網頁的自適應布局和px轉rem方案

一黎休、CSS3 Media Queries

  • Media Queries定義
    其作用就是允許添加表達式用以確定媒體的環(huán)境情況,以此來應用不同的樣式表。(換句話說毁涉,其允許我們在不改變內容的情況下,改變頁面的布局以精確適應不同的設備锈死。 )
  • 使用方式(兩種)
  1. 方式一:直接在link中判斷設備的尺寸贫堰,然后引用不同的css文件:
// 當屏幕的寬度大于600小于800時,應用styleB.css
 <link rel="stylesheet" type="text/css" href="styleB.css"  media="screen and (min-width: 600px) and (max-width: 800px)">
在media屬性里:
(1)screen 是媒體類型里的一種待牵,CSS2.1定義了10種媒體類型其屏;
(2)and 被稱為關鍵字,其他關鍵字還包括 not(排除某種設備)缨该,only(限定某種設備)偎行;
(3)(min-width: 400px) 就是媒體特性,其被放置在一對圓括號中贰拿。
  1. 方式二:即是直接寫在<style>標簽里:
@media screen and (max-width: 600px) { /*當屏幕尺寸小于600px時睦优,應用下面的CSS樣式*/
      .class {
          background: #ccc;
       }          
  }

寫法是前面加@media,其它跟link里的media屬性相同壮不。

其實基本上就是樣式覆蓋~,判斷設備皱碘,然后引用不同的樣式文件覆蓋询一。 
要注意的是由于網頁會根據(jù)屏幕寬度調整布局,所以不能使用絕對寬度的布局,也不能使用具有絕對寬度的元素癌椿。這一條非常重要健蕊,否則會出現(xiàn)橫向滾動條。

二踢俄、calc()

calc()使用通用的數(shù)學運算規(guī)則缩功,但是也提供更智能的功能:

>使用“+”、“-”都办、“*” 和 “/”四則運算嫡锌;
>可以使用百分比虑稼、px、em势木、rem等單位蛛倦;
>可以混合使用各種單位進行計算;
>表達式中有“+”和“-”時啦桌,其前后必須要有空格溯壶,如"widht: calc(12%+5em)"這種沒有空格的寫法是錯誤的;
>表達式中有“*”和“/”時甫男,其前后可以沒有空格且改,但建議留有空格。

例如 :設置div元素的高度為當前窗口高度-80px
 div{
   height: calc(100vh - 80px);     
}
或者利用%計算寬度
如: width: calc(100% - 10px)板驳;

vw Viewport寬度又跛, 1vw 等于viewport寬度的1%
vh Viewport高度, 1vh 等于viewport高的的1%

三笋庄、rem

在JS引入rem效扫,動態(tài)改變html的font-size。用rem動態(tài)改變字體大兄鄙啊:

;(function(win) {
    var tid;
    function refreshRem() {
        let designSize = 1920; // 設計圖尺寸
        let html = document.documentElement;
        let wW = html.clientWidth;// 窗口寬度
        let rem = wW * 100 / designSize; 
        document.documentElement.style.fontSize = rem + 'px';
    }
    win.addEventListener('resize', function() {
        clearTimeout(tid);
        tid = setTimeout(refreshRem, 300);
    }, false);
    win.addEventListener('pageshow', function(e) {
        if (e.persisted) {
            clearTimeout(tid);
            tid = setTimeout(refreshRem, 300);
        }
    }, false);
    refreshRem();
})(window);

四菌仁、px 轉 rem 方案

  • less,sass,stylus三種預處理器px2rem
  1. less
 //定義一個變量和一個mixin
 @baseFontSize: 75;//基于視覺稿橫屏尺寸/100得出的基準font-size
 .px2rem(@name, @px){
     @{name}: @px / @baseFontSize * 1rem;
 }

//使用示例:
.container {
   .px2rem(height, 240);
}

//less翻譯結果:
.container {
   height: 3.2rem;
}
  1. sass
//定義一個變量和一個mixin
$baseFontSize: 16;//默認基準font-size
@mixin px2rem($name, $px){
  #{$name}: $px / $baseFontSize * 1rem;
}
 
// 使用示例:
 .container {
   @include px2rem(height, 240);
 }
 
//  scss翻譯結果:
  .container {
    height: 3.2rem;
  }
  1. stylus
//定義一個變量和一個mixin
$baseFontSize = 16; //默認基準font-size
px2rem(name, px){
{name}: px / $baseFontSize * 1rem;
}
 
// 使用示例:
.container {
  px2rem('height', 240);
}
 
//  stylus翻譯結果:
.container {
  height: 3.2rem;
}

建議將mixin放入單獨文件夾下,例如webpack中的common,之后使用只需要在style中引入静暂,以scss為例:

@import "../common/scss/mixin.scss";
 
  .all {
    @include px2rem(padding, 32);
  }
  • flexible插件
    此處案例屬于vue項目中引用
  1. 安裝
npm i lib-flexible --save

2.引入lib-flexible
在main.js中引入lib-flexible:

import 'lib-flexible'
  1. 使用px2rem-loader自動將css中的px轉換成rem
  • 安裝px2rem-loader:
npm install px2rem-loader --save-dev
  • 配置px2rem-loader:
    (1)打開build/utils.js文件济丘,找到exports.cssLoaders方法,在里面添加如下代碼:
const px2remLoader = {
    loader: 'px2rem-loader',
    options: {
      remUint: 75,  //設計稿寬度/10, 以設計稿750為例洽蛀, 750 / 10 = 75
    }
  }

(2)打開build/utils.js文件摹迷,找到generateLoaders方法, 添加px2remLoader 插件:

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

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

(3)build/utils.js文件 添加 generateSassResourceLoader方法:

function generateSassResourceLoader () {                
       const loaders = [
          cssLoader,
          px2remLoader,
          'less-loader'
       ]
       if (options.extract) {
          return ExtractTextPlugin.extract({
             use: loaders,
             fallback: 'vue-style-loader'
          })
       } else {
           return ['vue-style-loader'].concat(loaders)
       }
    }

(4)修改 build/utils.js文件 return

return {
     css: generateLoaders(),
     postcss: generateLoaders(),
     less: generateSassResourceLoader()                //  修改less的值
} 
  • 如果是大屏需要修改flexible源碼
    打開./node_modules/lib-flexible/flexible.js,找到如下片段源碼:
function refreshRem(){
    var width = docEl.getBoundingClientRect().width;
    if (width / dpr > 540) {
        width = width * dpr;
    }
    var rem = width / 10;
    docEl.style.fontSize = rem + 'px';
    flexible.rem = win.rem = rem;
}
  • 重啟郊供,完成
    修改完成后峡碉,重啟項目,則會適配到相應的尺寸驮审。此外還有一個提示鲫寄,當脫離掉node_modules重新npm install項目依賴時還是需要重新修改一遍的,千萬別忘了疯淫!
  • 為解決重新安裝依賴需要再次配置地来,按以下方法:
    先把flexible.js源碼文件拷貝到項目下,然后修改改文件熙掺,此處提到了src文件下未斑,然后需要修改main.js里的引入路勁:
import './flexible'

此處在提出的文件如出現(xiàn)eslint報錯問題,可在文件頂部加上/* eslint-disable */即可币绩。

  • 問題1:1px的邊框也會幫你轉成rem蜡秽。
//對于有些地方不用轉換的我們可以在樣式后面添加/*no*/這樣就不會給我們轉化了;
.box{
        width:200px;
        height:200px;
        border-radius: 50%;
        border:1px solid red;/*no*/
    }

在px后面添加/no/府阀,不會轉化px,會原樣輸出载城。 — 一般border需用這個
在px后面添加/px/,會根據(jù)dpr的不同肌似,生成三套代碼〈ǘ樱—- 一般字體需用這個

  • 使用px2rem配合scss時固额,/px/斗躏、/no/失效:
    (1)可以把px寫成大寫PX啄糙,這樣px2rem也不會轉換隧饼,同時大寫在瀏覽器上也是生效的。
    (2)使用普通css寫拐格,也可以生效捏浊。

但是使用px2rem-loader修改build/utils.js文件之后會影響css樣式中的背景圖片的加載撞叨,為解決該問題選擇卸載px2rem-loader,使用postcss-pxtorem劣领。

postcss-pxtorem是PostCSS的插件尖淘,用于將像素單元生成rem單位惊暴。

  • 安裝
npm install postcss-pxtorem --save-dev
  • 配置
    可以通過3個地方來添加配置,配置文件皆位于vue 項目根目錄中辽话,若文件不存在可以自行建立。
  • 權重
    vue.config.js > .postcssrx.js > postcss.config.js
    其中 postcssrc.js 和 postcss.config.js 可以熱更新益咬, vue.config.js 中做的修改要重啟devServer。
  • 屬性
    rootValue (Number)

根元素的值冗锁,即1rem的值
用于設計稿元素尺寸/rootValue
比如 rootValue = 192 時蒿讥,設計稿是1920*1080比例芋绸,在css中width: 960px; 最終會換算成width: 5rem;
還有一些其他的配置:

propList (Array) 需要做單位轉化的屬性.

必須精確匹配
用 * 來選擇所有屬性. Example: ['']
在句首和句尾使用 * (['
position'] 會匹配 background-position-y)
使用 ! 來配置不匹配的屬性. Example: ['
', '!letter-spacing']
組合使用. Example: ['', '!font']
minPixelValue(Number) 可以被替換的最小像素.
unitPrecision(Number) rem單位的小數(shù)位數(shù)上限.

  • 配置示例
    vue.config.js
module.exports = {
  //...其他配置
  css: {
   loaderOptions: {
    postcss: {
     plugins: [
      require('postcss-pxtorem')({
       rootValue: 192,
       minPixelValue: 2,
       propList: ['*'],
      })
     ]
    }
   }
  },
 }

.postcssrc.js

module.exports = {
  plugins: {
    'postcss-pxtorem': {
      rootValue: 16,
      minPixelValue: 2,
      propList: ['*'],
    }
  }
}

postcss.config.js

module.exports = {
 plugins: {
  'postcss-pxtorem': {
   rootValue: 192,
   minPixelValue: 2,
   propList: ['*'],
  }
 }
}

這樣配合flexible即可實現(xiàn)px轉rem的適配全封。
如果不適用flexible刹悴,則新建rem.js文件土匀,于main.js中引用。

// 設計稿以1920px為寬度田度,而我把頁面寬度設計為10rem的情況下
 
const baseSize = 192; // 這個是設計稿中1rem的大小,此處要和postcss-pxtorem配置中的rootValue一致镇饺。
function setRem() {
  // 實際設備頁面寬度和設計稿的比值
  const scale = document.documentElement.clientWidth / 1920 || document.body.clientWidth / 1920;
  // 計算實際的rem值并賦予給html的font-size
  document.documentElement.style.fontSize = (baseSize * scale) + 'px';
}
setRem();
window.addEventListener('resize', () => {
  setRem();
});
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市李茫,隨后出現(xiàn)的幾起案子秸侣,更是在濱河造成了極大的恐慌,老刑警劉巖搏色,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異航邢,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來虑鼎,“玉大人掀鹅,你說我怎么就攤上這事。” “怎么了痢缎?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵世澜,是天一觀的道長独旷。 經常有香客問我,道長寥裂,這世上最難降的妖魔是什么嵌洼? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮封恰,結果婚禮上麻养,老公的妹妹穿的比我還像新娘。我一直安慰自己诺舔,他們只是感情好鳖昌,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著低飒,像睡著了一般许昨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上逸嘀,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天车要,我揣著相機與錄音,去河邊找鬼崭倘。 笑死翼岁,一個胖子當著我的面吹牛,可吹牛的內容都是我干的司光。 我是一名探鬼主播琅坡,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼残家!你這毒婦竟也來了榆俺?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎茴晋,沒想到半個月后陪捷,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡诺擅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年市袖,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烁涌。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡苍碟,死狀恐怖,靈堂內的尸體忽然破棺而出撮执,到底是詐尸還是另有隱情微峰,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布抒钱,位于F島的核電站蜓肆,受9級特大地震影響,放射性物質發(fā)生泄漏谋币。R本人自食惡果不足惜症杏,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瑞信。 院中可真熱鬧厉颤,春花似錦、人聲如沸凡简。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽秤涩。三九已至帜乞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間筐眷,已是汗流浹背黎烈。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留匀谣,地道東北人照棋。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像武翎,于是被迫代替她去往敵國和親烈炭。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345