移动端适配

奴止
Sep 24, 2022
Last edited: 2022-10-8
type
Post
status
Published
date
Sep 24, 2022
slug
mobile-adaption
summary
移动端适配 rem 和 vw 方案以及原理解释。
tags
前端开发
category
技术随手记
icon
password
Property
Oct 8, 2022 01:51 PM
 

背景

 
假设拿到设计稿的是基于 375px 宽来设计的,其中有个按钮,宽 * 高200px * 40px,最简单的就是直接用设计图上元素的尺寸来写css:
button { width: 200px; height: 40px; }
 
我们知道,这样肯定不行,不同的终端上肯定展示不同:那适配说的是什么?当然是保持和设计稿中一样的比例,我们以适配宽度来说(一般也就是适配宽度):
375 / realScreenWidth = 200 / realButtonWidth // 高度类似不再赘述 375 / realScreenWidth = 40 / realButtonHeight
 
上面 realButtonWidth 得变随着 realScreenWidth 变化而变化,可我们又只写同一份样式代码🤔,css 里相对单位 %、rem、vw 呼之欲出。
 

rem 方案

 
rem 是根据 html 上的 font-size 进行计算的,如若 html 的 font-size 100px,那么 1rem 表示 100px
 
对应到上面的按钮,那我们直接取 200rem?可以,但考虑到默认情况下 html 的字体大小是 16px,打开个空页面在 console 里输入这个试试:
getComputedStyle(document.documentElement)['font-size'] // '16px'
,个人建议还是保持原样?
 
我们继续等比例的问题:
375 / realScreenWidth = 200 / realButtonWidth 200px = 12.5rem // html font-size 16px realButtonWith = 12.5rem // html font-size x???
 
嗯……看起来,问题好像归到了 html 的 font-size 上了
375 / realScreenWidth = 16 / x
 
那我们只需要根据屏幕宽度去设置 html 的font-size 为 16*375/realScreenWidth 就可以了。
 
然而在实际项目里,我们肯定不想自己去做元素尺寸px到rem的换算,即使我们选择了375设计稿的html font-size为 100px 这种比例,那么上述例子中的按钮样式为:
button { width: 2rem; height: 0.4rem; }
 
也依然觉得费劲,直接保持和设计稿 1:1 代码难道不更清爽么。
 
广大网友大佬们肯定早想过这个问题了,下面这不是方案么。

即食方案

  • lib-flexible: 设置 html 的font-size,还有其它功能如处理屏幕大小变化时动态计算等,当然你也可以自己选择去实现
 
以 vue3 + vite 的配置为例:
// vite.config.ts export default defineConfig({ // ... 省略其它 css: { postcss: { plugins: [ pxtorem({ rootValue: 37.5, })] } } }) // src/main.ts import 'amfe-flexible/index.js'
 
⚠️
此方案无法做到行内样式的自动转换。
 

备注

 
忽略 px 到 rem 的转换可以这样写:
// `Px` or `PX` is ignored by `postcss-pxtorem` but still accepted by browsers .ignore { border: 1Px solid; // ignored border-width: 2PX; // ignored }
 
如果有用到 prettier 格式化,可以通过注释来禁止px 的大小写被格式为小写
.ignore { // prettier-ignore border-width: 2PX; }
 

vw 方案

 
和 rem 类似,直接可以使用方案 postcss-px-to-viewport
 

参考

vitepress组件示例实现vue3 + vite 常见问题