移动端适配以及多屏幕自适应方案

本文介绍了移动端适配问题,重点讲解了meta-viewport标记的使用、rem字体单位的应用、vw/vh视口单位以及如何通过postcss转换插件实现全局px到视口单位的转换,为移动端开发提供了解决方案。
摘要由CSDN通过智能技术生成


前言

本文主要记录适配移动端以及多屏幕的解决办法,还有postcss转换插件的编写。


一、移动端适配问题

在MDN中提到:

在移动设备和其他窄屏设备中,某些内容在比普通屏幕更宽的虚拟窗口或视口中渲染页面,然后缩小渲染的结果,以便可以一次看到所有内容。然后,用户可以通过平移和缩放以查看页面的不同区域。例如,如果移动屏幕的宽度为 640px,则页面可能会使用 980px 的虚拟视口渲染,然后页面将缩小以适应 640px 的空间。

横向滚动条

换成通俗易懂的话就是说,为了适配窄屏,他会把渲染视口以短边进行截断,然后就出现了横向滚动条,让用户能够左右滑动来查看完整的页面,但是这样做对移动端有很大的问题,左右滑动对移动端的用户体验大打折扣。
所以需要某种机制或者方法来适配移动端。
以下是最为常见的移动端适配方案。


二、meta-viewport标记

meta标签写在<head>标签中

<head>
    <meta charset="UTF-8">
<!--    移动端适配-->
    <meta name="viewport" content="with=device-width,initial-scale=1.0">
    <title>Title</title>
</head>

其中有很多选项用来调整视口与屏幕的关系

  • width
    控制视口的大小。这可以设置为特定像素数(如’width=600’),也可以设置为特殊值device-width,即 100vw,100% 的视口宽度。最小值为 1。最大值为 10000。负值会被忽略。

  • height
    控制视口的大小。这可以设置为特定像素数(如 width=600),也可以设置为特殊值 device-height,即 100vh,100% 的视口高度。最小值为 1。最大值为 10000。负值会被忽略。

  • initial-scale
    控制页面首次加载时显示的缩放倍数。最小值是 0.1。最大值是 10。默认值为 1。负值会被忽略。

  • minimum-scale
    控制页面允许缩小的倍数。最小值是 0.1。最大值是 10。默认值为 1。负值会被忽略。

  • maximum-scale
    控制页面允许放大的倍数。设置一个低于 3 的值将不具备无障碍访问性。最小值是 0.1。最大值是 10。默认值为 1。负值会被忽略。

  • user-scalable
    控制是否允许页面上的放大和缩小操作。有效值为 0、1、yes 或 no。默认值为 1,与 yes 相同。将值设置为 0(即与 no 相同)将违反 Web 内容无障碍指南(WCAG)。

  • interactive-widget
    指定交互式 UI 组件(如虚拟键盘)对页面视口的影响。有效值:resizes-visual、resizes-content 或 overlays-content。默认值:resizes-visual。

  • viewport-fit
    设置为 cover 可以解决 刘海屏 的留白问题

最终完整的meta标签可以写成:

<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">

在创建vue项目时,他会在index.html中自动加入这个标签。

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + Vue + TS</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

优点:

  • 不需要考虑一些屏幕计算问题,直接使用设计稿中的数值就可以

缺点:

  • 存在兼容问题,部分安卓机识别不了完整的meta属性
  • 使整个页面都进行了适配,导致某些不用适配的也参与了适配
  • 图片会失真

三、rem字体适配

rem是个长度单位,表示相对根元素的字体大小,例如根元素为14px,那么1rem表示14px,2rem表示28px。
利用JS控制根元素的字体大小就可以控制整个页面的字体大小的适配
首先是需要获取当前视口宽,利用宽动态调整根元素字体大小document.documentElement.clientWidth
利用window.onresize监听当前窗口变化

其中关键点是以下的两个点:

  • 计算对应宽度的根元素字体大小

    这个一般设计稿会给,设计稿都是固定某个宽,上边对应的字体大小就是这个宽对应的字体大小,就比如设计稿给我们一个宽375px,字体28px的设计稿,那么其他宽度对应的字体大小就是:其他宽度 × 28 ÷ 750

  • 计算子元素字体与根元素对应关系
    这个也是根据设计稿计算个比例就可以了,例如一个根元素是28px,子元素是14px,那么转换成rem就是:14 ÷ 28 = 0.5 rem
    这个也有一些插件可以实现将px自动转换成rem,如postcss-pxtorem,参考文章:px自动转rem

<style>
  .box{
    font-size: 3rem;
  }
  #text{
      font-size: 0.5rem;
  }
</style>
<body>
<div class="box">
  smz
</div>
<div id="text"></div>
</body>
<script>
  function adapter() {
    const text = document.querySelector('#text')
    //获取布局视口宽度,布局视口=设备横向独立像素值
    const dpWidth = document.documentElement.clientWidth
    //计算根字体大小
    const rootFonstSize = (dpWidth * 28)/375
    //设置根字体大小
    document.documentElement.style.fontSize = rootFonstSize + 'px'
    text.innerText = `当前根元素字体大小:${document.documentElement.style.fontSize}`
  }
  adapter()
  // 监听窗口变化
  window.onresize = adapter
</script>

rem


四、vw和vh

vw和vh也是长度单位,他与传统的以像素为单位不同,他是以视口百分比为单位
对于百分比布局有一定的区别,百分比是相对于父元素,尔vw和vh是相对于视口的

  • 1vw:表示视口宽度的百分之1
  • 1vh:表示视口高度的百分之1

也就是说100vw和100vh表示整个视口

使用vw和vh就不用再使用JS控制了
同样,使用此单位也需要计算设计稿中px与视口比例关系:对应像素长度 × 100vw ÷ 设计稿屏幕像素宽

less文件:

body{
  @basic:375/100vw;
  .box{
    width: 300/@basic;
    height: 150/@basic;
    background: red;
    margin: auto;
  }
}

vw


五、postcss转换插件

在vite开发的项目中集成了postcss,可以利用postcss编写一个全局转换的的一个方法,可以快速将px转换成vw,或者对某些可以做到不转换。

  • 在项目目录下新建plugins目录用来存放插件

  • 在tsconfig.node.json下添加配置项
    tsconfig.node.json

  • 在plugins目录下新建ts文件编写插件

import {Plugin} from "postcss";
// 默认宽度
const Options = {
    viewportWidth: 375 //UI设计稿宽度
}
interface Options {
    viewportWidth?:number
}
export const PostcssPxToViewport = (options:Options = Options):Plugin =>{
    const opt = Object.assign({},Options,options)// 将Options,options复制到同一对象中
    return {
        postcssPlugin : "postcss-px-to-viewport",// 名称
        //钩子函数 取css结点
        Declaration(cssNode){
            // 这里可以改名字‘smz’ 改成需要转换的,比如‘smz’ 就只针对 单位为'smz'的css结点进行转换
            if (cssNode.value.includes('smz')){// cssNode.value.includes('px')对含有px单位的css结点,可更改
                const num = parseFloat(cssNode.value)// 转换成数字去掉px
                cssNode.value =  `${(( num / opt.viewportWidth) * 100).toFixed(2)}vw` // 计算公式
            }
        }
    }
}
  • 在vite.config.ts引入注册插件

引入插件

使用:

<template>
<div class="box">
  postcss转换插件
</div>
  <div class="box2">
    普通未转换
  </div>
</template>

<style scoped>
.box{
  width: 200smz;
  height: 100smz;
  font-size: 20smz;
  border: 3px solid red;
}
.box2{
   width: 200px;
   height: 100px;
   font-size: 20px;
  border: 3px solid yellow;
 }
</style>

postcss转换插件

总结

以上三种方案,是相互搭配进行移动端的适配的。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天将降大任于我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值