跳转到内容

前端不同屏幕尺寸自适应与大屏移动端开发

刀刀

4/7/2025

0 字

0 分钟

    学习明灯
  • UP主:三十的前端课,视频地址:前往学习

核心思想

  1. 基本原则:布局更多使用 flex ,尺寸使用 remvwvh 等单位,字体使用 emrem 等单位
  2. 如果根据不同屏幕做不同的布局,一般通过 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 = 16px0.5rem = 8pxrem 之所以能自适应就是根据屏幕大小用 js 重新设置 html 字体大小。

算法为:html 字体大小 = (js 获取到的当前设备宽度 / 设计图宽度) * 设计图宽度下 1rem 大小

该方法主要难点在于需要自己手动计算,可以使用第三方插件和依赖简化:

  1. vscode 下载插件 px to rem ,可以自动将 px 转换为 rem
  2. 使用 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% 的屏幕高度。使用 vwvh 可以实现自适应,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 灵活
百分比根据父组件来计算样式响应式调整依赖父组件

其他注意事项

  1. 关于边距处理:靠左靠右用 flex ,顶开部分小距离 remvw
  2. 图片一般定宽不定高,防止图片变形。如果屏幕跨度过大,可能会导致图片大得夸张,此时可以考虑图片设置最大宽度然后居中
  3. 一些大屏可视化项目中,界面必须是刚刚好满屏幕不能溢出不能短,用 f11 切换全屏会引起高度变化,这种需求有些高度可以用 vh