您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
前端 | 小程序横竖屏的坑和 rpx 布局方案
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
前端 | 小程序横竖屏的坑和 rpx 布局方案
京东科技IoT团队
2021-02-03
IP归属:未知
1144000浏览
前端
小程序
### 问题背景 开发小程序,当我们按设计图用 rpx 以宽为参照基础(即 750rpx = 宽的大小),写好了样式,放到真实设备上看时发现样式和设计图差别很大。 研究了很久发现,我们的真实设备是一个横屏设备。 调用 `getSystemInfo()` 获取系统信息: { "screenWidth": 1024, "screenHeight": 600, } 横屏的定义🧐? 宽大于高 => 横屏 宽小于高 => 竖屏 **当横屏的时候,小程序的 rpx 是根据屏幕的高度进行自适应的**,即屏幕的 screenHeight 为 750rpx,而不是 screenWidth > 实际试了一下,京东小程序和微信小程序表现都是这样 ### 解决方案 1. `边锁定` 保证在横竖屏切换的时候内容大小不变 不管是横屏还是竖屏,750rpx 总是对应着最短的那条边。 借助 vmin,`100vmin = 750rpx`, > vmin: 通俗的讲就是将宽、高中的最短边均分成100单位的vmin,1vmin就是最短边的1%。 假设视觉稿按照 ip 的 750px 进行设计,短的边为 750px,于是就有 100vmin = 750rpx = 750px 如果我们要设置视觉稿大小为 18px 的字体,我么可以在小程序中使用 ```css font-size: calc(18vmin / 7.5); ``` 占比:字体大小/最短边大小 = 18px / 750px 实际大小:占比 * 100vmin 即 18vimn / 7.5,其实和 rpx 没关系,弃用了 rpx 这种动态计算的方法。 🤔其实这种方法是自动选择了最小边为参照,那么小程序的最小边也总是对应着 750rpx,我们也可以 18px/750px * 750 rpx 得到字体实际大小。 所以在开发的时候**重点是要选取最小边为参照基准**。 这样我们的字体大小始终会和最短边的大小保持一定的比例,最短边的大小是固定的,所以字体大小也是固定的,并不会随着屏幕横竖的切换而改变。 2. **使用 sass 自定义函数计算 rpx** 弄清楚解决问题的重点是始终以固定短边来做参考后,其实用 rpx 也是一样的, 毕竟 rpx 也是锁定最短边。 但是直接使用很难计算,而且如果要改变方案,比如不用 rpx ,而使用 px + 自适应来布局,得全部重新改,很麻烦。 所以我们利用 sass 的优势(为啥不用 less,less 不支持自定义函数……),来解决这个问题 ```scss // 视觉稿最短边大小 $baseWidth: 700; @function toRpx($px) { @if unitless($px) { @return $px / $baseWidth * 750rpx; } @else { @return $px / ($px * 0 + 1) / $baseWidth * 750rpx; } } // usage .test { width: toRpx(700px); .test-child { border: toRpx(350) solid red; } } // 输出的样式 .test { width: 750rpx; } .test .test-child { border: 375rpx solid red; } ``` 如果需要变动,改 toRpx 函数即可。 再利用 `chokidar` 和 `dart-sass` 监听和自动编译 scss,写起来就很方便了😊 ```js const fs = require("fs"); const path = require("path"); const chalk = require("chalk"); const chokidar = require("chokidar"); var sass = require("sass"); (function() { const rootPath = path.resolve(); console.log(chalk.green("Scss2jxss is listening...")); chokidar .watch([`${rootPath}/**/*.scss`, `${rootPath}/**/*.css`], { ignored: path => path.includes("node_modules") }) .on("add", async path => { await writeFile(path); console.log(); log("Add", `${path} file success!`, "bgGreen"); }) .on("change", async path => { await writeFile(path); console.log(); log("Change", `${path} file success!`, "bgCyan"); }) .on("unlink", path => { fs.unlinkSync(convertExt(path)); console.log(); log("Unlink", `${path} file success!`, "bgRed"); }); })(); function convertExt(filename) { return filename.replace(/(.scss|.css)$/, ".jxss"); } function writeFile(path) { let output = sass.renderSync({ file: path }); fs.writeFileSync(convertExt(path), output.css); } function log(label, msg, color) { console.log(chalk.black[color](label), msg); } ``` 🤔:用 sass 的自定义函数可以自动计算 rpx 实现视觉稿等比布局的效果,写起来比较方便简单。也可以用 px 写自适应布局,麻烦但是效果好。。。 > 作者: 熊枭龙
原创文章,需联系作者,授权转载
上一篇:浏览器(基于Chromium)运行机制剖析
下一篇:京东支付SDK重构设计与实现
相关文章
前端十年回顾 | 漫画前端的前世今生
Taro小程序跨端开发入门实战
【技术干货】企业级扫描平台EOS关于JS扫描落地与实践!
京东科技IoT团队
文章数
13
阅读量
110382
作者其他文章
01
前端 | 小程序横竖屏的坑和 rpx 布局方案
如何避免小程序开发过程中的那些“坑”
01
前端 | Chrome 80 中 Iframe cookie 无法携带的问题
Chrome 80 中 Iframe cookie 无法携带的问题求解过程。
01
NLU | 智能音箱语义理解——MDIS三合一模型
MDIS模型(Unified Model for Multiple Domain Intent and Slot)可以做到同时对话术进行领域分类、意图判断以及填槽。
01
前端 |数据大屏适配方案
数据大屏适配方案详解
最新回复
丨
点赞排行
共0条评论
京东科技IoT团队
文章数
13
阅读量
110382
作者其他文章
01
前端 | Chrome 80 中 Iframe cookie 无法携带的问题
01
NLU | 智能音箱语义理解——MDIS三合一模型
01
前端 |数据大屏适配方案
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号