移动端框架,适配各种尺寸屏幕方案
概述:做移动端的适配我们就是要考虑,对于不同大小的手机屏幕,怎么动态改变页面布局中所有盒子的宽度高度、字体大小等
一、方案预览
方案一:百分比设置(不推荐)
- 因为不同属性的百分比值,相对的可能是不同参照物,所以百分比往往很难统一
方案二:vw 单位 + rem单位(推荐- 需考虑兼容问题)
- vw ,就是根据窗口的宽度,分成 100 等份,100vw 就表示满宽,50vw 就表示一半宽。(vw 始终是针对窗口的宽),同理,vh 则为窗口的高度
- 窗口:可视区域(即 window.innerWidth/window.innerHeight 大小,不包含任务栏标题栏以及底部工具栏的浏览器区域大小)
- 这个写法跟使用js 动态html的font-size 大小是一个原理,给html 定义一个 font-size: calc(100 / 375 * 100vw); 效果跟下方js代码方式是一致的
- font-size: calc(100 / 375 * 100vw); 假设项目设置的是 1rem = 100px; 利用vm定义算出对应1rem 对应的vm
方案三:rem 单位+动态 html 的 font-size(后面讲解)(推荐)
- 媒体查询 (后面讲解)
- 编写 js (后面讲解)
方案四:flex 的弹性布局
- 弹性布局针对的是盒子本身,对字体大小这块没有特别好的办法
- 建议配和方案三来使用
二、媒体查询(rem 单位)
- 可以通过媒体查询来设置不同尺寸范围内的屏幕 html 的 font-size 尺寸;
- 缺点:
- 我们需要针对不同的屏幕编写大量的媒体查询;
- 如果动态改变尺寸,不会实时的进行更新;(媒体查询只能修改某个范围区间里面的 html 的字体大小,在这个区间里面,盒子大小都是一样的,我们是希望实时改变的)
/* 当屏幕宽度小于320px时 */
@media screen and (max-width: 320px) {
/* 可以在这里为特定元素添加样式,或者再次调整font-size */
}
/* 当屏幕宽度在321px到480px之间时 */
@media screen and (min-width: 321px) and (max-width: 480px) {
/* 更多样式调整 */
html {
font-size: 24px; /* 假设我们想要在这个尺寸范围内使用稍小一点的字体 */
}
}
三、编写js代码(rem 单位)
- 如果希望实时改变屏幕尺寸时,font-size也可以实时更改,可以通过js代码;
- 方法:
- 根据html的宽度计算出font-size的大小,并且设置到html上;
- 监听页面的实时改变,并且重新设置font-size的大小到html上;
- 代码示例:将下面代码放到app.vue中;严格来说下面代码只会执行一次-性能问题可以忽略要是不放心的话可以加一个节流方法
function adjustFontSize() {
var baseSize = 100 // 设计稿中375px时的 font-size
var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
var rem = width / (375 / baseSize) // 基准缩放
document.documentElement.style.fontSize = `${rem}px`
}
// 初始设置
adjustFontSize()
// 监听窗口变化 throttle 节流方法
window.addEventListener('resize', throttle(adjustFontSize, 100))
四、方案推荐 使用vw方案实现 配合postcss-px-to-viewport-8-plugin插件处理vant 等框架适配问题
- 使用vw 时需要注意配合 postcss-px-to-viewport-8-plugin 插件使用;才能在vant 等框架中生效
- postcss-px-to-viewport-8-plugin 是一个 CSS 解析和转换工具,它工作在 CSS 源代码上,而不是 HTML 文档,因此它无法直接处理 HTML 中的行内样式。
- HTML 中的行内样式 需要单独处理,这里给出两种处理方案:
- 使用 JavaScript 来动态地读取和修改 DOM 中的行内样式。这可以通过遍历 DOM 元素并查找包含 px 单位的样式属性来实现,然后使用 JavaScript 将其转换为 vw/vh。(这种方式会存在性能问题-不推荐)
- 需要写行内样式的时候将px 单位转成 rem 或者 vw ;
- install postcss-px-to-viewport-8-plugin 安装和使用
npm install postcss-px-to-viewport-8-plugin --save-dev
vite.config.ts 文件中
import postcsspxtoviewport8plugin from 'postcss-px-to-viewport-8-plugin'
export default ({ mode }) => {
// ...
return defineConfig({
// ...
css: {
// ...
postcss: {
plugins: [
postcsspxtoviewport8plugin({
unitToConvert: 'px',
viewportWidth: 375,
unitPrecision: 5, // 单位转换后保留的精度
propList: ['*'], // 能转化为vw的属性列表
viewportUnit: 'vw', // 希望使用的视口单位
fontViewportUnit: 'vw', // 字体使用的视口单位
selectorBlackList: ['ignore-'], // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位。
minPixelValue: 1, // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
mediaQuery: true, // 媒体查询里的单位是否需要转换单位
replace: true, // 是否直接更换属性值,而不添加备用属性
exclude: [], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
include: [], // 如果设置了include,那将只有匹配到的文件才会被转换
landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
landscapeUnit: 'vw', // 横屏时使用的单位
landscapeWidth: 1628, // 横屏时使用的视口宽度
}),
],
},
},
})
})