增强 vw/rem 移动端适配,适配宽屏、桌面端、三折屏
vw 和 rem 是两个神奇的 CSS 长度单位,认识它们之前,我一度认为招聘广告上的“像素级还原”是一种超能力,我想具备这种能力的人,一定专业过硬、有一双高分辨率的深邃大眼睛。
时间一晃,入坑两年,我敏捷地移动有点僵硬不算过硬的小手,将一些固定的 px 尺寸复制到代码,等待编译阶段的 vw/rem 转换,刷新浏览器的功夫,完美还原的界面映入眼前,我推了推眼镜,会心一笑。多亏了 vw 和 rem。
TLDR:极简配置 postcss-mobile-forever 增强 vw 的宽屏可访问性,限制视图最大宽度。
用 vw 和 rem 适配移动端视图的结果是一致的,都会得到一个随屏幕宽度变化的等比例伸缩视图。一般使用 postcss-px-to-viewport 做 vw 适配,使用 postcss-px2rem 配合 amfe-flexible 做 rem 适配。由于 rem 适配的原理是模仿 vw,所以后面关于适配的增强,一律使用 vw 适配做对比。
vw 适配有一些优点(同样 rem):
- 加速开发效率;
- 像素级还原设计稿;
- 也许更容易被自动生成。
但是 vw 适配也不完美,它引出了下面的问题:
- 开发过程机械化,所有元素是固定的宽高,不考虑响应式设计,例如不使用
flex、grid布局; - 助长不规范化,不关注细节,只关注页面还原度和开发速度,例如在非按钮元素的
<div>上添加点击事件; - 桌面端难以访问,包容性降低。
前两个问题,也许要抛弃 vw、回归响应式布局才能解决,在日常开发时,我们要约束自己以开发桌面端的标准来开发移动端页面,改善这两个问题。
马克·吐温在掌握通过密西西比河的方法之后,发现这条河已经失去了它的美丽——总会丢掉一些东西,但是在艺术中比较不受重视的东西同时也被创造出来了。让我们不要再注意丢掉了什么,而是注意获得了什么。 ——《禅与摩托车的维修艺术》
后面,我们将关注第三点,介绍如何在保持现状(vw 适配)的情况下,尽可能提高不同屏幕的包容性,至少让我们在三折屏的时代能得到从前 1 倍的体验,而不是 1/3。
| 移动端 | 桌面端 |
|---|---|
![]() |
![]() |
上面是一个页面分别在手机和电脑上展示的截图,可以看到左图移动端的右上角没有隐藏分享按钮,所以用户是允许(也应该允许)被分享到桌面端访问的,可惜,当用户准备享受大屏震撼的时候,真的被震撼了:他不知道这个页面的技术细节是神奇的 vw,也不知道他只能用鼠标小心地拖动浏览器窗口边缘,直到窗口窄得和手机一样,最崩溃的是,当他得意地按下了浏览器的缩小按钮,页面像冰冷的机器纹丝不动,浇灭了他的最后一点自信。
限制最大宽度
由于 vw 是视口单位,因此当屏幕变宽,vw 元素也会变大,无限变宽,无限变大。
现在假设在一张宽度 600 像素的设计图上,有一个宽度 60px 的元素,最终通过工具,它会被转为 10vw。这个 10vw 元素是任意伸缩的,但是现在我希望,当屏幕宽度扩大到 700px 后,停止元素的放大。
出现了一堆枯燥的数字,不用担心,后面还有一波,请保持耐心。
首先计算 10vw 在宽 700 像素的屏幕上,应该是多少像素:60 * 700 / 600 = 70。通过最大宽度(700px)和标准宽度(600px)的比例,乘以元素在标准宽度时的尺寸(60px),得到了元素的最大尺寸 70px。
接着结合 CSS 函数:min(10vw, 70px),这样元素的宽度将被限制在 70px 以内,小于这个宽度时会以 10vw 等比伸缩。
除了上面的作为正数的尺寸,可能还会有用于方位的负数,负数的情况则使用 CSS 函数 max(),下面的代码块是一个具体实现:
/**
* 限制大小的 vw 转换
* @param {number} n
* @param {number} idealWidth 标准/设计稿/理想宽度,设计稿的宽度
* @param {number} maxWidth 表示伸缩视图的最大宽度
*/
function maxVw(n, idealWidth = 600, maxWidth = 700) {
if (n === 0) return n;
const vwN = Math.round(n * 100 / idealWidth);
const maxN = Math.round(n * maxWidth / idealWidth);
const cssF = n > 0 ? "min" : "max";
return `${cssF}(${vwN}vw, ${maxN}px)`;
}
矫正视图外的元素位置
上一节提供的方法,包容了限制最大宽度尺寸的大部分情况,但是如果不忘像素级还原的️初心,就会找到一些漏洞。
下面是一个图例,移动端页面提供了 Top 按钮用于帮助用户返回顶部,按照上一节的方法,Top 按钮会出现在中央移动端视图之外、右边的空白区域中,而不是矫正回中央移动端视图的右下角。

假设 Top 按钮的样式是这样的:
.top {
position: fixed;
right: 30px;
bottom: 30px;
/* ... */
}
按照标准宽度 600、最大宽度 700,上面的 30px 都被转换成了 min(5vw, 35px),bottom 没错,但 right 需要矫正。
对照上面右图矫正过的状态,right 的值 = 右半边的空白长度 + Top 按钮到居中视图右边框的长度 = 桌面端视图的一半 - 视图中线到 Top 按钮的右边框长度。
沿着第二个等号后面的思路,fixed 定位时桌面端视图一半的尺寸即为 50%,中线到 Top 按钮右边框的长度,分两种情况:
- 在屏幕宽度大于最大宽度 700 时,为 700 / 2 - 30 * 700 / 600,即为
315px(其中 700 / 2 是中线到移动端右边框长度,30 * 700 / 600 是屏宽 600 时的30px在屏宽 700 时的尺寸); - 在屏幕宽度小于最大宽度 700 时,为 (600 / 2 - 30) / 600,即为
45%。
结合 calc()、min() 和上面得到的 50%、315px、45%,参考第二个等式,可以得到 right 的新值为 calc(50% - min(315px, 45%))。当尺寸大于移动端视图的一半时,会出现负数的情况,这时使用 max() 替换 min()。
上面的计算方法是一种符合预期的稳定的方法,另一种方法是强制设置移动端视图的根元素成为包含块,设置之后,
right: min(5vw, 35px)将不再基于浏览器边框,而是基于移动端视图的边框。
postcss-mobile-forever
上面介绍了增强 vw 以包容移动端视图在宽屏展示的两个方面,除了介绍的这些,还有一点点边角情况,例如:
- 逻辑属性的判断和转换;
- 矫正
fixed定位时和包含块宽度有关的vw和%尺寸; - 矫正
fixed定位时left与right的vw和%尺寸; - 为移动端视图添加居中样式;
- 各种情况的判断和转换方法选择。
postcss-mobile-forever 是一个 PostCSS 插件,利用 mobile-forever 这些工作可以在编译阶段完成,上面举了那么多例子,汇总成一份 mobile-forever 配置就是:
{
"viewportWidth": 700,
"appSelector": "#app",
"maxDisplayWidth": 600
}
上面是 mobile-forever 用户使用最多的模式,max-vw-mode,此外还提供:
- mq-mode,media-query 媒体查询模式,生成可访问性更高的样式,同样限制最大宽度,但是避免了
vw带来的无法通过桌面端浏览器缩放按钮缩放页面的问题,也提供了更高的浏览器兼容性; - vw-mode,朴素地将固定尺寸转为 vw 伸缩页面,不限制最大宽度。
postcss-mobile-forever 相比 postcss-px-to-viewport 提供了更多的模式,包容了宽屏展示,相比 postcss-px2rem,无需加载 JavaScript,不为项目引入复杂度,即使用户禁用了 js,也能正常展示页面。
scale-view 提供运行时的转换方法。
优秀的模版
postcss-mobile-forever 的推广离不开开源模版的支持、尝试与反馈,下面是这些优秀的模版,它们为开发者提供了更多元的选项,为用户提供了更包容的产品:
- vue3-vant-mobile,一个基于 Vue 3 生态系统的移动 web 应用模板,帮助你快速完成业务开发。【查看在线演示】
- vue3-vant4-mobile,基于Vue3.4、Vite5、Vant4、Pinia、Typescript、UnoCSS等主流技术开发,集成 Dark Mode(暗黑)模式和系统主题色,且持久化保存,集成 Mock 数据,包括登录/注册/找回/keep-alive/Axios/useEcharts/IconSvg 等其他扩展。你可以在此之上直接开发你的业务代码!【查看在线演示】
- fantastic-mobile,一款自成一派的移动端 H5 框架,支持多款 UI 组件库,基于 Vue3。【查看在线演示】

增强后的 vw/rem 看起来已经完成了适配宽屏的任务,不过回想最初的另外两个问题,机械化的开发过程与不规范化的开发细节,没有解决。作为一名专业的前端开发工程师,请考虑使用响应式设计开发你的下一个项目,为三折屏带来 3 倍的用户体验吧。
增强 vw/rem 移动端适配,适配宽屏、桌面端、三折屏的更多相关文章
- 利用vw+rem实现移动web适配布局
基本概念 1.单位 Px(CSS pixels) 像素 (px) 是一种绝对单位(absolute units), 因为无论其他相关的设置怎么变化,像素指定的值是不会变化的 其实是相对于某个设备而言的 ...
- 了解css中px、em、rem的区别并使用Flexible实现vue移动端的适配
本人java菜鸟一名,若有错误,还请见谅. 1.px和em和rem的定义和区别 px:px像素,是相对单位,相对于屏幕的分辨率而言,也就是说,当屏幕的分辨率不同那么px相同,实际看到的大小也会不同. ...
- 移动 web 端屏幕适配 - rem
前言 最近整理了一下以前学习前端的笔记,发现自己对移动 web 端屏幕适配(rem)这一块并没有真正理解,只是会用.接下来,把自己的一些对移动 web 端屏幕适配(rem)的思考记录下来. rem 介 ...
- 九、响应式发:rem和less(适配移动端)
一.响应式开发 响应式开发优先适配移动端又兼容到pc端 官网:https://less.bootcss.com/usage/ 教程:https://www.w3cschool.cn/less/ rem ...
- 移动端屏幕适配(rem+js)
什么是移动端适配 在制作webapp时,一个很关键的问题就是适配各种机型不同屏幕的大小,让每种机型上的布局看起来都尽量一样. 也就是说用同一套代码在不同分辨率的手机上跑时,页面元素间的间距.留白,以及 ...
- webapp新体验Rem实现移动端网页适配详解资源
本来想写一篇,webapp使用Rem的问题,查了一下相关rem的介绍之后,发现很多平台已经解释的很清楚了,图文并茂,于是我便想将其解释资源整理一些,方便以后自己查阅. 腾讯ISUX:web app变革 ...
- 移动端font-size适配方案
概述 这是我研究移动端页面时的思考,记录下来供以后开发时参考,相信对其他人也有用.由于我写移动端页面写的还比较少,一些问题都还没遇到,所以我的这篇博文不免有些错误的地方,还请大佬多多指正. 这篇文章是 ...
- Web 端屏幕适配方案
基础知识 像素相关 1.像素 :像素是屏幕显示最小的单位. 2.设备像素 :设备像素又称物理像素(physical pixel),设备能控制显示的最小单位,我们可以把这些像素看作成显示器上一个个的点. ...
- 国内外移动端web适配屏幕方案
基础知识点 设备像素:设备像素又称物理像素(physical pixel),设备能控制显示的最小单位,我们可以把这些像素看作成显示器上一个个的点. iPhone5的物理像素是640X1136. PS: ...
- 移动端font-size适配方案(续)
概述 之前写过一篇移动端font-size适配方案,但是在实践过程中,还是发现当时的思维太局限了,视野太窄了,所以现在补充更新一下,记录下来,供以后开发时参考,相信对其他人也有用. 我上一篇博文主要有 ...
随机推荐
- TGI 多-LoRA: 部署一次,搞定 30 个模型的推理服务
你是否已厌倦管理多个 AI 模型所带来的复杂性和高成本? 那么, 如果你可以部署一次就搞定 30 个模型推理服务会如何? 在当今的 ML 世界中,哪些希望充分发挥其数据的价值的组织可能最终会进入一个& ...
- 火山引擎ByteHouse助力车企实现高性能数据分析
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群. 新能源汽车市场正在迎来飞速发展时期.根据 IDC 预测,中国乘用车市场中,新能源车市场规模将在2028年超过 ...
- .netcore生命周期、消息管道
.NET Core 的初始化过程涉及多个步骤,这些步骤从应用程序的启动开始,一直到应用程序准备好处理请求.下面是一个简化的概述,描述了 .NET Core 应用程序(特别是 ASP.NET Core ...
- .proto文件的作用
在网络通信和通用数据交换等应用场景中经常使用的技术是 JSON 或 XML,而在最近的开发中接触到了 Google 的 ProtoBuf. 在查阅相关资料学习 ProtoBuf 以及研读其源码之后,发 ...
- Ubuntu 设置远程桌面(VNC)
连接 Xfce 4 远程桌面 下载 Xfce 4 桌面环境: sudo apt install -y xfce4 xfce4-goodies 这里会提示你设置显示管理器,我们设置 gdm3 就好. 安 ...
- uni-app 小程序用户信息之头像昵称填写
小程序获取用户头像昵称,微信又叒做妖,废除之前的接口,改成了头像昵称填写 通知:微信小程序端基础库2.27.1及以上版本,wx.getUserProfile 接口被收回,详见<小程序用户头像昵称 ...
- vue打包后dist的使用
发现问题 vue项目完成打包出dist后准备打开index.html,发现居然页面是一片空白,f12一片报红. 分析问题 经过多次网上查询后发现这是由于vue打包时,脚手架会帮你配置好大量参数,但其中 ...
- 【YashanDB知识库】应用绑定参数的慢查询,慢日志抓取不到
[问题分类]功能使用 [关键字]慢日志.绑定参数 [问题描述]应用下发的绑定参数的SQL,慢日志功能抓取不到查询耗时超过阈值的执行SQL [问题原因分析]慢日志的功能没有考虑绑定参数的情况 [解决/规 ...
- C#/.NET/.NET Core优秀项目和框架2024年8月简报
前言 公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的介绍.功能特点.使用方式以及部分功能截图 ...
- 用PowerDesigner创建Oracle模型转为mysql模型
一.首先打开PowerDesigner 1.File(位置:左上角)–>New Model–>Physical Date Model(物理数据模型) (1)DBMS选择MySQL5.0(版 ...

