Skip to content

移动端大屏端布局适配

作者:Yuan Tang
更新于:5 个月前
字数统计:1.4k 字
阅读时长:4 分钟

核心思想

  1. 布局更多使用 flex ,尺寸使用 remvwvh 为单位
  2. 根据不同屏幕尺寸需要不同布局,采用多个站点切换或者媒体查询使用 css

rem

页面尺寸计算

以 HTML 字体大小为 1rem 的大小,HTML 为 16px ,1rem 则为 16px。rem之所以能自适应就是根据屏幕大小用 js 重新计算设置 1rem 的大小。

计算公式为:页面宽度 除以 设计稿宽度(一般是750)再乘想要设置 1rem 为多少 px (这里取 1rem 为 16px)。

来到 index.htmlApp.vue 组件,计算 1rem 的大小。步骤如下:

  1. 获取整体页面宽度
  2. 根据比例计算 1rem 的大小
  3. 为整体 HTML 根元素添加字体大小的样式
  4. 绑定页面尺寸修改事件,触发事件后重新计算
js
function resizeFn() {
  const fontSize = (document.body.clientWidth / 750) * 16
  document.documentElement.style.fontSize = `${fontSize}px`
}
resizeFn()

window.addEventListener('resize', resizeFn)

如果想要给整体项目添加最大宽度,则用页面整体宽度和最大宽度做比较取最小值。

js
const fontSize = (Math.min(document.body.clientWidth, 750) / 750) * 16 // [!code++]
document.documentElement.style.fontSize = `${fontSize}px`

现在可以把页面元素样式单位修改为 rem,保存刷新后就可查看效果。

第三方库使用

手动一个个把 px 改成 rem 费时费力,开发效率低下,引入第三方库 postcss-pxtorem 可以有效提高开发效率。该第三方库可以在运行时和打包部署后自动帮我们转换单位。

  • 下载依赖

    pnpm i postcss-pxtorem
  • vite.config.js 引入

    js
    import postcsspxtorem from 'postcss-pxtorem'
  • 配置

    js
    export default defineConfig({\
      css: {
        postcss: {
          plugins: [
            postcsspxtorem({
              rootValue: 16, // ui设计稿宽度 / 10
              unitPrecision: 3, // 指定`px`转换为视窗单位值的小数位数
              propList: ['*'], // 需要转换的属性列表,*表示全部(如果设置width,则width的值会被转换)
              selectorBlackList: ['ignore'], // 指定不需要转换的类
              replace: true, // 是否直接更换属性值,而不添加备用属性
              mediaQuery: false, // 是否在媒体查询的css代码中也进行转换,默认false
              minPixelValue: 0, // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
              exclude: /node_modules/i // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
            })
          ]
        }
      }
    })

现在可以解放双手,放心大胆的设置单位为 px ,它会帮我们自动转为 rem

注意

使用这个第三方库还是要在 index.htmlApp.vue 组件设置根元素的字体大小样式,否则不生效。

vw,vh

1vw-1%视口宽度,1vh-1%视口高度。

假设屏幕宽高为750*1200,那么 1vw 就是75px,1vh就是120。

使用vw做单位无需要做计算,因为vw会自动根据屏幕宽度变化,vh一般用来做全屏设计。

对应的自动转化库:postcss-px-to-viewport

第三方库

  • 下载依赖

    pnpm i postcss-px-to-viewport
  • 引入

    js
    import postcsspxtoviewport from 'postcss-px-to-viewport'
  • 配置

    js
    export default defineConfig({\
      css: {
        postcss: {
          plugins: [
            postcsspxtorem({
              // ...
            }),
      			postcsspxtoviewport({
      				unitToConvert: 'apx', // 想要转换的单位
      				viewportWidth: 750,
              unitPrecision: 6,
              propList: ['*'], // 需要转换的属性列表,*表示全部(如果设置width,则width的值会被转换)
      				viewportUnit: 'vw', // 指定需要转换成的单位,默认vw
              selectorBlackList: ['ignore'], // 指定不需要转换的类
      				minPixelValue: 1, // 默认值1,小于或等于1ox不做转换
      				mediaQuery: false, // 是否在媒体查询的css代码中也做转换,默认false
              replace: true, // 是否直接更换属性值,而不添加备用属性
    				})
          ]
        }
      }
    })

百分比

百分比是相对于父元素的百分比,所以一般除非是最外层的容器,否则不具备响应式调整的功能。

方案对比

rem VS vw

两个方案都可以用于控制某个盒子的大小,都会根据屏幕宽度灵活变化。rem相对于ww灵活度更高,如果你的移动端项目还需要web端浏览,那么 rem 可以做到 vw 做不到事情。如果页面单纯是在移动端看(比如app内web)。

rem不去监听resize事件,去修改fontSize是做不到在动态改变屏幕宽度时变化大小的。如果不想监听 resize 事件,或者变化触发不了 resize ,使用vw。

百分比

百分比并不是一无是处,rem和vw都是根据屏慕去算的,如果我们需要根据父组件去缩放我们可以就必须用百分比了,比如父元素是一个用 js 计算出来的尺寸的盒子,我们现在希望里面的两个内容一个占百分之30,一个占百分之70。

其他注意事项

  1. 关于边距处理-靠左靠右这种用flex,顶开部分小距离rem,ww
  2. 图片一般都定宽不定高,防止图片变形,但是如果如果屏幕跨度过大,可能会导致图片大到很夸张,可以考虑把图片设置最大宽度,然后居中,避免过长
  3. 在一些大屏可视化项目中,界面必须是刚好满屏幕的,不能溢出不能短。但是当通过f11切换全屏,会引起高度变化,rem和vw是不会变化的。所以这种需求的项目,有的高度可以用vh来做。

总体效果

总体效果可前往tydumpling博客查看,地址

Contributors

Yuan Tang