移动端采用Flexible将PX转换REM适配及开发中Retina屏1px边框的两种解决方案

说明:两个方案均基于Webpack构建。

方案一:

搭建环境及相关配置

  • webpack 3,需要loader及说明
  • css-loader, style-loader 加载css文件
  • expose-loader 暴露全局例如jquery
  • url-loader 样式文件内的图片等资源
  • file-loader 字体等资源

使用库和主要插件

  • jquery
  • normalize
  • lib-flexible 0.3.2
  • px2rem + px2rem-loader

要解决一些问题

自适应这里采用了旧版的flexible,并通过px2rem来进行单位转换,关于样式中的px值是否转换为rem或者输出多种对应不同dpr的px值,请查看插件说明进行对应的注释,例如/*no*//*px*/。这里有一点需要说明的是,与mobileweb不同的是,旧版的flexible具有最大宽度1080(540*dpr)的问题?也就是说当屏幕宽度大于1080的时候,两边会留出空白,而无法占满屏幕?如有错误,望指正截取一段flexible代码:

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加上一段居中样式:

body {max-width: 750px; /* 设计稿最大宽度 */margin: 0 auto;
}

这样当设备宽度大于设计稿的宽度时,则整体页面居中,更加美观。(再次强调mobileweb中用的最新的flexible会自动扩展到满屏,不存在该问题。)

附加:关于webpack配置写法参考

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,其他参数可自行参考文档。

注1:

这个demo依然有引入PostCSS,因为webpack下没有一个很好autoprefixer的loader(其实有一个autoprefixer-loader,该loader也提示了autoprefixer官方推荐使用postcss-loader替代),因此依然加入了PostCSS混合SASS开发。

注2:

不太确定如果单位写成PX是否会存在兼容性问题,不过在高级浏览器和我测试的几部手机观察来看未发生异常。

假设通过将单位故意大写为PX而避免转换的话,是不是相对尾部写/*no*/来进行过滤更为方便?

发现这个特征的是在学习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;
}

方案二(之前SF笔记上有,此处有更新):

搭建环境及相关配置

  • webpack 3,需要loader及说明
  • css-loader, style-loader 加载css文件
  • postcss-loader 对css进行转换处理
  • expose-loader 暴露全局例如jquery
  • url-loader 样式文件内的图片等资源
  • file-loader 字体等资源

使用库

  • jquery
  • normalize
  • amfe-flexible

PostCSS相关的插件

  • autoprefixer
  • postcss-advanced-variables
  • postcss-nested
  • postcss-partial-import
  • postcss-pxtorem
  • postcss-scss
  • postcss-sorting
  • cssnano
  • postcss-property-lookup
  • postcss-adaptive(该插件实际上与pxtorem功能相似,似乎是px2rem的改进版,需配合lib-flexible该插件为了解决1px边框问题而生,其实是配合类名对dpr2进行px/2的处理。如果需求不高可以直接采用该插件,而放弃同时使用postcss-pxtorem和postcss-adaptive,我之所以同时使用主要是因为postcss-pxtorem的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宽,这里设置简单说明一下(没说的是我还没弄明白或者是不重要的?):

  • rootValue为75,说是对根元素大小进行设置。可能类似px2rem中的remUnit参数吧
  • unitPrecision为5,起初我真不知道这个官方说的The decimal numbers to allow the REM units to grow to.是啥意思,搞了半天才观察出来,原来是转换成rem后保留的小数点位数。。。
  • propList是一个存储哪些将被转换的属性列表,这里设置为['*']全部,假设需要仅对边框进行设置,可以写['*', '!border*']意思是排除带有border的属性,当然这里会有一个问题,也许有时候不想对border其他样式处理例如border-radius所以也不是很好。
  • selectorBlackList则是一个对css选择器进行过滤的数组,比如你设置为['fs'],那例如fs-xl类名,里面有关px的样式将不被转换,这里也支持正则写法。
  • minPixelValue是一个非常不错的选项,我设置了12,意思是所有小于12px的样式都不被转换,那么border之类的属性自然会保留px值了。而刚才提到的border-radius如果为了创造圆形等特殊较大圆弧时则还是会转换成rem,来配合对应的width和height(当然,你也可以用继承width或者height的变量来设置radius)。

需要注意的是,以下情况并不会保留为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-adaptive说明

在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属性进行操作,这是我们不希望的,合理的操作有两种:

  1. 将圆角值按照设计稿(假设设计稿时10px)设定,并重新调整postcss-pxtorem配置中的minPixelValue为两倍安全值,例如12
  2. 将圆角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个地方。。。然后过了几天思考,又全部还原了采用了方案一(因为项目不方便转换为方案二)。

因此,方案三只是留给大家思考一下,也就没有什么实际的使用价值了。

移动端采用Flexible将PX转换REM适配及开发中Retina屏1px边框的两种解决方案相关推荐

  1. VUE中引入插件实现px转换rem

    1.使用命令行安装lib-flexible: npm install lib-flexible --save 2.引入lib-flexible: 在项目入口文件 main.js 里 引入 lib-fl ...

  2. WebStorm设置px转换rem,亲测有效!

    为了保证网页的响应式设计,我们在H5开发中用的单位一般都是rem,怎么在WebStorm中设置自动将px转换rem呢?非常简单,只需要安装一个插件即可. 步骤: WebStorm --> Pre ...

  3. WebStorm设置px转换rem插件

    为了保证网页的响应式设计,我们在H5开发中用的单位一般都是rem,怎么在WebStorm中设置自动将px转换rem呢?非常简单,只需要安装一个插件即可. 步骤: WebStorm --> Pre ...

  4. vscode px转换rem插件 px to rem rpx vw (cssrem)

    vscode px转换rem插件px to rem & rpx & vw (cssrem) 这个插件非常好用,我给3星! 选中按Alt + Z可以px和rem转换

  5. 移动端的开发详解与1px边框等注意事项

    移动端开发 我们现在关注的点还在移动M站上,或者我们可以叫做webapp,其实就是运行在移动端浏览器中的web网站. app:application应用程序. 手机软件:主要指安装在智能手机上的软件, ...

  6. 7种方法实现移动端Retina屏幕1px边框效果

    在Reina(视网膜)屏幕的手机上,使用CSS设置的1px的边框实际会比视觉稿粗很多.在之前的项目中,UI告诉我说我们移动项目中的边框全部都变粗了,UI把他的设计稿跟我的屏幕截图跟我看,居然真的不一样 ...

  7. 7种方法解决移动端Retina屏幕1px边框问题

    造成边框变粗的原因 其实这个原因很简单,因为css中的1px并不等于移动设备的1px,这些由于不同的手机有不同的像素密度.在window对象中有一个devicePixelRatio属性,他可以反应cs ...

  8. html px转换rem,在线px转rem工具代码

    px转rem ,部署到本地服务器即可运行. px转rem body{font-family:"\5FAE\8F6F\96C5\9ED1",Helvetica;} ul{ list- ...

  9. sass px转rem适配方案

    // rem $browser-default-font-size: 16px ;html {font-size: $browser-default-font-size; }@media screen ...

最新文章

  1. 【思维训练】刺激战场极寒模式下带妹吃鸡的【兵法思维】和【统计学思维】
  2. [云炬Mysql数据库笔记] 第3章 数据定义
  3. urllib的实现---cookie处理
  4. centos6.6安装hadoop-2.5.0(四、hadoop HA安装)
  5. Istio 首次安全评估结果公布
  6. html按钮冻结,Vue js按钮冻结dom
  7. openlayers 3读取加载geojson格式数据
  8. 面试不谈钱,难道要我跟你谈恋爱?真会扯
  9. docker -v 挂载文件_浅谈关于docker中数据卷的操作,附带案例
  10. 系列有什么区别_哈弗的F系列和H系列,有什么区别?
  11. 我的RHCE考试终于要开始了!
  12. linux执行shell过程日志,Android之在linux终端执行shell脚本直接打印当前运行app的日志...
  13. [JAVA]使用Jersey处理Http协议中的Multipart
  14. 【luogu P2319 [HNOI2006]超级英雄】 题解
  15. 用VC实现洪水***程序
  16. :root选择器的妙用【2021.11.14】
  17. 计算机网络----数据交换方式虚电路
  18. (附完整代码和实验报告)【python 大作业】实现一个聊天机器人,关键词双重查找,结合语境查找,爬虫查询,图形化界面,语音播报。
  19. 爱可信携手Marvell展示爱可信Linux平台
  20. 追寻红色记忆、晋国文明之思考毕业季研学营

热门文章

  1. sftp 设置仅能访问自己目录的用户
  2. 软件构架实践_阅读笔记01(1-3)
  3. C# UdpClient使用Receive和BeginReceive接收消息时的不同写法
  4. 美国《预防》杂志近期帮大家总结了11种自然疗法来对抗高血压
  5. 一个常见的asp.net错误解决
  6. Remoting: Server encountered an internal error
  7. 判断链表是否是中心对称
  8. 诗和远方:无题(四十六)
  9. Uncaught SyntaxError: missing ) after argument list 错误解决
  10. Jsp之我遇到过的中文乱码问题和解决方法