说明:两个方案均基于Webpack构建。javascript
自适应这里采用了旧版的flexible,并经过px2rem来进行单位转换,关于样式中的px值是否转换为rem或者输出多种对应不一样dpr的px值,请查看插件说明进行对应的注释,例如/*no*/
和/*px*/
。这里有一点须要说明的是,与mobileweb不一样的是,旧版的flexible具备最大宽度1080(540*dpr)的问题?也就是说当屏幕宽度大于1080的时候,两边会留出空白,而没法占满屏幕?若有错误,望指正截取一段flexible代码:css
function refreshRem() { var width = docEl.getBoundingClientRect().width; if (width / dpr > 540) { width = 540 * dpr; } var rem = width / 10; docEl.style.fontSize = rem + 'px'; flexible.rem = win.rem = rem; }
这里有个小小的建议就是给body加上一段居中样式:java
body { max-width: 750px; /* 设计稿最大宽度 */ margin: 0 auto; }
这样当设备宽度大于设计稿的宽度时,则总体页面居中,更加美观。(再次强调mobileweb中用的最新的flexible会自动扩展到满屏,不存在该问题。)jquery
module: { rules: [{ test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.scss$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: [{ loader: "css-loader" }, { loader: "px2rem-loader", options: { remUnit: 75, threeVersion: true } }, { loader: 'postcss-loader' }, { loader: "sass-loader" }, ] }) }, { test: /\.(png|svg|jpg|gif)$/, use: [{ loader: 'url-loader', options: { limit: 4096 } }] }, { test: /\.(woff|woff2|eot|ttf|otf)$/, use: [ 'file-loader' ] }, { test: require.resolve('jquery'), use: [{ loader: 'expose-loader', options: 'jQuery' }, { loader: 'expose-loader', options: '$' }] } ] },
主要是px2rem-loader这里的对px2rem的相关配置,我这里设计稿750,所以设定75,其余参数可自行参考文档。webpack
注1:git
这个demo依然有引入PostCSS,由于webpack下没有一个很好autoprefixer的loader(其实有一个autoprefixer-loader,该loader也提示了autoprefixer官方推荐使用postcss-loader替代),所以依然加入了PostCSS混合SASS开发。github
注2:web
不太肯定若是单位写成PX是否会存在兼容性问题,不过在高级浏览器和我测试的几部手机观察来看未发生异常。npm
假设经过将单位故意大写为
PX
而避免转换的话,是否是相对尾部写/*no*/
来进行过滤更为方便?segmentfault发现这个特征的是在学习postcss的时候用到postcss-pxtorem插件,碰巧测试出来的。
固然我的倒的确倾向于写
PX
,若是不存在兼容性问题。示例:
转换前:.pic-txts { text-align: left; border:1px solid #ddd; /*px*/ border-radius: 5PX; width:690px; display: block; }转换后:
.pic-txts { text-align: left; border-radius: 5PX; width: 9.2rem; display: block; } [data-dpr="1"] .pic-txts { border: 0.5px solid #ddd; } [data-dpr="2"] .pic-txts { border: 1px solid #ddd; } [data-dpr="3"] .pic-txts { border: 1.5px solid #ddd; }
minPixelValue: 6
比较方便,以及对于不想转换的px处理的规则使用很是便捷!)快速开发自适应的移动端专题站点或简单页面
解决字体和边框不进行rem转换(根据考究并未找到合理有效的证据证实font-size建议使用px,我的认为若是rem计算合理不该该存在明显的重大问题。天然就不须要用到px2rem的dpr扩辗转换功能了)
该分支采用postcss-pxtorem避免了postcss-nested注释问题,具体配置大体以下
require('postcss-pxtorem')({ rootValue: 75, unitPrecision: 5, propList: ['*'], selectorBlackList: [], replace: true, mediaQuery: false, minPixelValue: 12 })
假设设计稿750宽,这里设置简单说明一下(没说的是我还没弄明白或者是不重要的?):
['*']
所有,假设须要仅对边框进行设置,能够写['*', '!border*']
意思是排除带有border的属性,固然这里会有一个问题,也许有时候不想对border其余样式处理例如border-radius
因此也不是很好。['fs']
,那例如fs-xl
类名,里面有关px的样式将不被转换,这里也支持正则写法。须要注意的是,如下状况并不会保留为px!
.test-radius { width:20px; height:20px; border-radius: calc(@width / 2); background-color:#ccc; }根据反复测试,calc运算是来自cssnano插件,然而cssnano有必要放在最后执行,因此没法知足计算后的10px在进行pxtorem转换,不过这种状况也是比较合理的。假设width和height转换为rem,而圆角是px,我的感受不可避免的会形成圆形错误的状况(是否有可能改圆角px值实际上永远大于转换后的rem的50%?有待考究!),因此这种状况暂时就不考虑了,让其单位均保持一致便可。
写到这里我又陷入了沉思,由于有个问题不明白了。根据postcss.config.js配置cssnano是在最后面,pxtorem是在其前面,那么如何作到对此段样式转换的顺序。
这段代码应该先是postcss-property-lookup对@width进行处理,而后进行calc(@width / 2)计算,最后对px检测转换,再进行cssnano压缩。而实际上有点诡异。难道postcss.config.js中插件的执行顺序并不是单纯的从上而下!但愿不久的未来这个疑问将被解决,或者我也怀疑postcss官方文档实际有指出,只是我的英文能力较差被我忽略掉了?。
另外一方面,关于此段CSS在画圆上有一些须要注意的,其实这里若是写圆用50%便可,我发现某些状况下(多是圆形很小)若是按照除以2的写法转换成rem彷佛不圆,因此在现代开发来看移动端画圆就50%了!因此上例仅作测试好了~
额外阅读,关于border-radius的一些事项。
对了忘了说了,css样式代码中将px写成Px
或者PX
他也不会转换成rem的~
在PostCSS的配置文件中,我加入了这个插件并放在了postcss-pxtorem的后面引入,这样在第一次转换后,postcss-adaptive的默认参数就不会影响到上一个插件的配置而形成的混乱状况。实际上前面也提到过,这个插件的大部分功能和postcss-pxtorem类似,区别在于对于转换规则的条件过滤,而postcss-pxtorem这点有极大的优点,使用这个插件主要是解决retina屏(iPhone4以上?)须要对1px边框处理为0.5px。具体测试能够看一下DEMO中的pic-txts结构,如下是该结构部分说明:
这是一个pic-txts结构的wrap,展现小圆角边框在两个rem > px 转换插件的做用下的影响由于在postcss-pxtorem配置中的minPixelValue设置为6,当圆角为5px时,他不进行转换,而postcss-adaptive却要对px属性进行操做,这是咱们不但愿的,合理的操做有两种:
- 将圆角值按照设计稿(假设设计稿时10px)设定,并从新调整postcss-pxtorem配置中的minPixelValue为两倍安全值,例如12
- 将圆角5px值改为postcss-pxtorem不处理的规则例如5PX,经过实验,发现postcss-adaptive并不会处理该属性
固然若是项目容易改造的话,仍是建议使用方案二,在适配上面已经作得很是完善了,方案二中1px的问题经过类名提升CSS优先级很是方便,也不须要更复杂的操做。PostCSS在这两年来依旧是发展趋势,在新的项目中能够大胆尝试。
方案三:
其实关于1px适配的问题,我想到了一个特别的方法,那就是在媒体查询中,声明一个变量例如:
$borderWidth: 1px; @media (max-resolution: 2dppx) { $borderWidth: 0.5px; }我但愿css变量能在符合该媒体查询规则的状况下覆盖以前声明的变量,然而这种操做是没法实现的!!!
固然,我后来只有这样写:
.test { border:1px solid #ccc; @media (max-resolution: 2dppx) { border-width:0.5px; } }但是你知道这样写有多么麻烦吗,大型项目中大量的代码须要批量处理的时候,这是不可能实现的,虽然我当时的确在项目里手动替换了超过50个地方。。。而后过了几天思考,又所有还原了采用了方案一(由于项目不方便转换为方案二)。
所以,方案三只是留给你们思考一下,也就没有什么实际的使用价值了。