前端不同屏幕尺寸自适应与大屏移动端开发
刀刀
4/7/2025
0 字
0 分钟
- UP主:三十的前端课,视频地址:前往学习
核心思想
- 基本原则:布局更多使用
flex
,尺寸使用rem
、vw
、vh
等单位,字体使用em
、rem
等单位 - 如果根据不同屏幕做不同的布局,一般通过
media
媒体查询 或检测屏幕尺寸换不同的站点
功能实现
检测屏幕尺寸换不同的站点
以百度为例,PC 端和移动端的布局完全不一样,使用 rem
肯定是无法实现,所以需要检测屏幕尺寸,然后跳转到不同的站点。可以使用 window.innerWidth
来检测屏幕宽度,然后根据宽度跳转到不同的站点。也可以对 link
标签使用 media
媒体查询,根据不同的屏幕宽度加载不同的样式。
js
if (window.innerWidth <= 799) {
window.location.href = "https://m.baidu.com";
}
html
<link
rel="stylesheet"
href="css/pc.css"
media="screen and (min-width: 800px)"
/>
<link
rel="stylesheet"
href="css/mobile.css"
media="screen and (max-width: 799px)"
/>
一般样式变化太大,就会使用这种方法,切换不同站点实现不同端的样式。
rem
以 html
字体大小为 1rem
的大小,html
为 16px,那么 1rem = 16px
,0.5rem = 8px
。rem
之所以能自适应就是根据屏幕大小用 js
重新设置 html
字体大小。
算法为:html
字体大小 = (js
获取到的当前设备宽度 / 设计图宽度) * 设计图宽度下 1rem 大小
该方法主要难点在于需要自己手动计算,可以使用第三方插件和依赖简化:
- vscode 下载插件
px to rem
,可以自动将px
转换为rem
- 使用
postcss-pxtorem
插件,自动将px
转换为rem
。如果不想要某些px
转换为rem
,可以采用style
行内式
html
<body>
<script>
// window.screen.scrollWidth: 获取设备的物理宽度,包括滚动条在内; document.body.clientWidth: 获取设备可用的宽度,不包括滚动条在内
let width = Math.min(document.body.clientWidth, 750); // 在屏幕大小和750px之间去最小值
let fontSize = (width / 750) * 16; // 设计图宽度为750px,设计图下1rem为16px
document.documentElement.style.fontSize = fontSize + "px";
</script>
</body>
js
import postcsspxtorem from "postcss-pxtorem";
export default {
css: {
postcss: {
plugins: [
postcsspxtorem({
rootValue: 16, // UI设计稿的宽度除以16
propList: ["*"], // 需要转换的属性,*代表所有属性
selectorBlackList: [".ignore", ".hairlines"], // 忽略的css选择器,不会转换为rem
exclude: /node_modules/i, // 排除的文件
minPixelValue: 2, // 最小的像素值,小于这个值的将不会被转换
mediaQuery: false, // 允许在媒体查询中转换px
replace: true, // 替换包含rem的规则,是否直接更换属性值而不添加备用属性
unitPrecision: 5, // 指定`px`转换为视窗单位值的小数位数(很多时候无法整除)
}),
],
},
},
};
vw、vh
1vw = 1% 的屏幕宽度,1vh = 1% 的屏幕高度。使用 vw
和 vh
可以实现自适应,vw
无需计算,会自动根据屏幕宽度变化;vh
一般用于做全屏设计。
可以使用对应的库 postcss-px-to-viewport
自动转换。
js
import postcsspxtorem from "postcss-pxtorem";
import postcsspxtoviewport from "postcss-px-to-viewport";
export default {
css: {
postcss: {
plugins: [
postcsspxtorem({
rootValue: 16, // UI设计稿的宽度除以16
propList: ["*"], // 需要转换的属性,*代表所有属性
selectorBlackList: [".ignore", ".hairlines"], // 忽略的css选择器,不会转换为rem
exclude: /node_modules/i, // 排除的文件
minPixelValue: 2, // 最小的像素值,小于这个值的将不会被转换
mediaQuery: false, // 允许在媒体查询中转换px
replace: true, // 替换包含rem的规则,是否直接更换属性值而不添加备用属性
unitPrecision: 5, // 指定`px`转换为视窗单位值的小数位数(很多时候无法整除)
}),
postcsspxtoviewport({
unitToConvert: "apx", // 需要转换的单位
viewportWidth: 750,
unitPrecision: 5, // 指定`px`转换为视窗单位值的小数位数(很多时候无法整除)
viewportUnit: "vw", // 指定需要转换成的视窗单位,默认vw
propList: ["*"], // 需要转换的属性,*代表所有属性
selectorBlackList: ["ignore-"], // 忽略的css选择器,不会转换为vw
fontViewportUnit: "vw", // 字体使用的视窗单位
minPixelValue: 1, // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
mediaQuery: false, // 允许在媒体查询中转换px
replace: true, // 是否直接更换属性值,而不添加备用属性
}),
],
},
},
};
vue
<style>
div {
width: 100px; /* 不会被转化 */
height: 100apx; /* 会转化为vw */
}
</style>
百分比
百分比是相对于父元素的百分比,所以一般除非是最外层的容器,否则不具备响应式调整的功能。
方案对比
方案 | 优点 | 缺点 |
---|---|---|
rem | 相比 vw 更灵活,对于移动端与 PC 端都需要的项目更灵活 | 移动端不监听 resize 重新修改 htmlFontSize 无法实现 |
vw | 不需要监听页面 resize 事件更好用 | 需要移动端和 PC 端都适配样式时没 rem 灵活 |
百分比 | 根据父组件来计算样式 | 响应式调整依赖父组件 |
其他注意事项
- 关于边距处理:靠左靠右用
flex
,顶开部分小距离rem
、vw
- 图片一般定宽不定高,防止图片变形。如果屏幕跨度过大,可能会导致图片大得夸张,此时可以考虑图片设置最大宽度然后居中
- 一些大屏可视化项目中,界面必须是刚刚好满屏幕不能溢出不能短,用
f11
切换全屏会引起高度变化,这种需求有些高度可以用vh