一黎休、CSS3 Media Queries
- Media Queries定義
其作用就是允許添加表達式用以確定媒體的環(huán)境情況,以此來應用不同的樣式表。(換句話說毁涉,其允許我們在不改變內容的情況下,改變頁面的布局以精確適應不同的設備锈死。 ) - 使用方式(兩種)
- 方式一:直接在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) 就是媒體特性,其被放置在一對圓括號中贰拿。
- 方式二:即是直接寫在<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
- less
//定義一個變量和一個mixin
@baseFontSize: 75;//基于視覺稿橫屏尺寸/100得出的基準font-size
.px2rem(@name, @px){
@{name}: @px / @baseFontSize * 1rem;
}
//使用示例:
.container {
.px2rem(height, 240);
}
//less翻譯結果:
.container {
height: 3.2rem;
}
- sass
//定義一個變量和一個mixin
$baseFontSize: 16;//默認基準font-size
@mixin px2rem($name, $px){
#{$name}: $px / $baseFontSize * 1rem;
}
// 使用示例:
.container {
@include px2rem(height, 240);
}
// scss翻譯結果:
.container {
height: 3.2rem;
}
- 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項目中引用
- 安裝
npm i lib-flexible --save
2.引入lib-flexible
在main.js中引入lib-flexible:
import 'lib-flexible'
- 使用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();
});