集中適配方案的總結: 項目: https://github.com/Aluka-w/mobile-terminal-adaptation
rem和vw布局
總結:
- 舊的rem布局
典型: lib-flexible: flex通過Hack手段來根據(jù)設備的dpr值相應改變<meta>標簽中viewport的值, 使得rem模擬vw的效果
- 新的vw布局(我的demo里面并沒有解決兼容)
設計稿
設計稿大多是750px * 1334px, css像素是750px, dpr=2, 基本按750布局即可
設備像素比(dpr) = 物理像素 / 設備獨立像素(css像素)
vh, vw(頁面可視寬度 + 滾動條)
參考: https://www.w3cplus.com/css/vw-for-layout.html
vw:是Viewport's width的簡寫,1vw等于window.innerWidth的1%
vh:和vw類似,是Viewport's height的簡寫,1vh等于window.innerHeihgt的1%
視口被均分為100單位的vh, 既100vh就是滿屏高, 均等分可能出現(xiàn)像素偏差, 并且有兼容性
cssrem插件
設置的
cssrem.rootFontSize
這個參數(shù)是: 每次設置值都會除以這個參數(shù)返回的 值 + rem = 最后數(shù)值手淘團隊針對計算的問題, 有寫less或者sass的函數(shù)
第一不依賴框架
依賴cssrem這個插件(網(wǎng)易的做法)
demo: WY-mobile
function initRem() {
// 7.5基準值: 設計稿寬度 / 100 = 基準值
var deviceWidth = document.documentElement.clientWidth;
// 當大于750時候就按照750寬度計算
if(deviceWidth > 750) deviceWidth = 750;
document.documentElement.style.fontSize = deviceWidth / 7.5 + 'px';
}
initRem();
window.addEventListener("resize", function () {
initRem();
});
-
第二步
設置: ```cssrem.rootFontSize = 100 ```, 即設計稿的值都除以100即可
-
第三步
height的設置需要注意, 可能填不滿
-
第四步:
這種方案下, 不想使用rem, 那就直接用px即可
手淘團隊的lib-flexible方案(vue中也有)
demo: ali-mobile
與網(wǎng)易團隊的區(qū)別: 手淘動態(tài)增加meta標簽, 動態(tài)計算dpr, 兼容更多的屏 demoa: ali-mobile
參考: https://www.w3cplus.com/mobile/lib-flexible-for-html5-layout.html
-
步驟:
- 引入lib-flexible(或者直接引入)
`<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script>`
- 刪除meta標簽
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
-
cssrem的設置
cssrem的
cssrem.rootFontSize = 75
, 就可以了 這種方案下, 不想使用rem, 那就直接用px即可
依賴cssrem這個插件(博客)
demo: normal-mobile
- 第一步
;(function(win, doc){
function fontSizeModify() {
var idealWidth = doc.documentElement.clientWidth,
htmlEle = doc.children[0];
fontSize = 32 * idealWidth/750;
// 當寬度大于600時, font-size保持不變
// if (idealWidth >=600) {
// fontSize = 32 * 600/750;
// }
htmlEle.style.fontSize = fontSize + "px";
}
function throttle(method, content) {
clearTimeout(method.tId);
method.tId = setTimeout(function() {
method.call(content);
}, 100);
}
fontSizeModify();
win.addEventListener("resize", function(){
throttle(fontSizeModify);
});
})(this, document);
- 第二步
設置: cssrem.rootFontSize = 32
, 因為乘以了32的原因
- 這種方案下, 不想使用rem, 那就直接用px即可
第二, Vue-cli的手機適配
px轉rem(手淘團隊的lib-flexible)demo: vue-normal
參考: https://blog.csdn.net/qq_22844483/article/details/79730604
步驟:
npm install lib-flexible --save
在main.js引入
import 'lib-flexible/flexible.js'
把項目根目錄的index.html 頭部刪除自動生成的meta標簽, lib-flexible會根據(jù)屏幕自動生成相對于的meta標簽
安裝
npm install px2rem-loader --save-dev
把px轉成rem修改build/utils.js, 在cssLoader變量中
const cssLoader = {
loader: 'css-loader',
options: {
sourceMap: options.sourceMap,
importLoader: 5 // 在加載cssLoader之前加載的loader個數(shù)
}
}
const px2remLoader = {
loader: 'px2rem-loader',
options: {
emUnit: 75 // 設計稿的1/10
}
}
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
})
})
}
}
-
關于px2rem(保留px方案)
- 直接寫px鸭廷,編譯后會直接轉化成rem
- 在px后面添加/no/,不會轉化px术羔,會原樣輸出。 — 一般border需用這個
- 在px后面添加/px/,會根據(jù)dpr的不同乃沙,生成三套代碼猎塞。---- 一般字體需用這個
之后直接根據(jù)設計稿寫就行
px轉成vw(重在學習) demo: vue-mobile
參考網(wǎng)址: https://www.w3cplus.com/mobile/vw-layout-in-vue.html
demo: vue-mobile
缺點: 兼容性較差
實現(xiàn)步驟:
安裝依賴:
npm i postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext postcss-viewport-units cssnano --S
在根目錄
.postcssrc.js
中, 對新安裝的PostCSS插件進行配置
"plugins": {
"postcss-import": {},
"postcss-url": {},
// "autoprefixer": {}, // 因為postcss-cssnext, cssnano都有類似功能
"postcss-aspect-ratio-mini": {}, // 處理元素容器寬高比, 感覺像scss的繼承, 沒什么卵用
"postcss-write-svg": { // 處理移動端1px的解決方案
utf8: false
},
"postcss-cssnext": {}, // 該插件可以讓我們使用CSS未來的特性,其會對這些特性做相關的兼容性處理
"postcss-px-to-viewport": { // 主要用來把px單位轉換為vw蔓罚、vh椿肩、vmin或者vmax
viewportWidth: 750, // 視窗的寬度,對應的是我們設計稿的寬度豺谈,一般是750
viewportHeight: 1334, // 視窗的高度覆旱,根據(jù)750設備的寬度來指定,一般指定1334核无,也可以不配置
unitPrecision: 3, // 指定`px`轉換為視窗單位值的小數(shù)位數(shù)(很多時候無法整除)
viewportUnit: 'vw', // 指定需要轉換成的視窗單位,建議使用vw
selectorBlackList: ['.ignore', '.hairlines'], // 指定不轉換為視窗單位的類藕坯,可以自定義团南,可以無限添加,建議定義一至兩個通用的類名
minPixelValue: 1, // 小于或等于`1px`不轉換為視窗單位噪沙,你也可以設置為你想要的值
mediaQuery: false // 允許在媒體查詢中轉換`px`
},
"cssnano": { // 主要用來壓縮和清理CSS代碼
preset: "advanced",
autoprefixer: false, // 插件是用來自動處理瀏覽器前綴的一個插件, 重復調用, postcss-cssnext已經(jīng)有了
"postcss-zindex": false // 啟用了這個插件,z-index的值就會重置為1吐根。這是一個天坑
}
}
- 保留px方案
通過添加類名, .ignore
, 可以配置
- 之后直接根據(jù)設計稿寫就行
第三, create-react-app搭配webpack做適配(事實上還是webpack)
px轉rem(手淘團隊的lib-flexible) demo: react-normal
參考: https://blog.csdn.net/zhuming3834/article/details/84319296
-
步驟:
- 安裝
cnpm i lib-flexible postcss-px2rem
2.找到
node_modules/react-scripy/config/webpack.config.dev.js
- 安裝
const px2rem = require('postcss-px2rem');
const getStyleLoaders = (cssOptions, preProcessor) => {
const loaders = [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: cssOptions,
},
{
loader: require.resolve('postcss-loader'),
options: {
ident: 'postcss',
// 這些是配置rem的
plugins: () => [
require('postcss-flexbugs-fixes'),
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009',
},
stage: 3,
}),
px2rem({remUnit: 75}) // 這里表示 75px = 1rem
],
},
},
{
loader: require.resolve('less-loader') // compiles Less to CSS
}
];
if (preProcessor) {
loaders.push(require.resolve(preProcessor));
}
return loaders;
};
- 找到
node_modules/react-scripy/config/webpack.config.prod.js
plugins: () => [
require('postcss-flexbugs-fixes'),
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009',
},
stage: 3,
}),
px2rem({remUnit: 75})
],
在index.js中引入import 'lib-flexible'
之后直接根據(jù)設計稿寫就行
px轉vw(手淘推出的vw布局) demo: react-mobile
步驟: 有點尷尬, 沒配置出來, demo沒有用