超详细讲解 H5 移动端适配方案

2023-10-26

REM适配方案

1. 前言

设计师交付给前端开发一张宽度为750px的视觉稿,设计稿上元素的尺寸、颜色、位置等已做过标注,要求工程师工在适配不同屏幕尺寸的设备时采用等比缩放的方案。
设计稿

2. 原理

在使用单位控制页面元素大小时,可以使用固定单位px,也可以使用相对单位rem。2rem 等于html标签font-size的2倍。基于这个原理,对于需要适配屏幕等比缩放的元素可以选用rem作为单位,对于不需要等比缩放的元素依旧使用px作为单位。只要调整html标签的font-size,就能让所有使用rem单位的元素跟随着发生变化,而使用px单位的元素不受影响。问题的关键在于如何根据屏幕尺寸跳转html标签的font-size。

举个实际的例子。设计师交付的设计稿宽度是750px,设计稿上一个div的标注尺寸是375px(宽度是设计稿宽度的一半)。我们可以

  1. 设置html的font-size 为 100*屏幕宽度/设计稿宽度
  2. 在写CSS时设置 div 的宽度是 3.75rem (计算时用设计稿标注值除以100),边框宽度为1px

假设用户在逻辑像素宽度是375px的设备上打开页面,则html的font-size是100*375/750 = 50px,div的宽度是3.75rem ,即187.5px 正好是屏幕宽度的一半。

假设用户在逻辑像素宽度是428px的设备上打开页面,则html的font-size是100*428/750 = 57.07px,div的宽度是3.75rem ,即214px 正好是屏幕宽度的一半。

为什么要用100来乘以屏幕宽度/设计稿宽度?其实100只是随便选取的一个值,我们也可以随便其他任意值比如50。如果选100,设计稿中某个元素标注的尺寸是375px,我们可以很快速的计算出3.75rem。如果html的font-size 设置为 50*屏幕宽度/设计稿宽度,那么div的宽度就应该是7.5rem了。换算起来就没那么直观了。

3. 适配代码

rem 适配代码只要 script 里面的

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,
    initial-scale=1, maximum-scale=1, minimum-scale=1">
  <script>
    const WIDTH = 750//如果是尺寸的设计稿在这里修改
    const setView = () => {
//设置html标签的fontSize
      document.documentElement.style.fontSize = (100*screen.width/WIDTH) + 'px'
    }
    window.onorientationchange = setView
    setView()
  </script>

  <style>
    div {
      width: 3.75rem;/* 需要随屏幕等比缩放,使用rem单位,比如设计稿中标注的32px这里写成0.32rem */
      border: 1px solid #ccc;/*不需要缩放的部分用px*/
    }
  </style>
</head>
<body>
  <div>内容</div>
</body>
</html>

如果想要在 vue 里引入可以仿照上面的写在 html 页面中,也可以新建一个 js 页面,写入适配代码,在 main.js 中全局引入,也可以局部引入,但是如果页面过多则不推荐局部引入

  • 在 vue 中引入代码:
import './rem'

4. 总结

动态Rem方案既能实现页面级整体缩放,又能个性化控制某些元素不缩放。

vw适配方案

1. 原理

vw是相对单位,1vw表示屏幕宽度的1%。基于此,我们可以把所有需要适配屏幕大小等比缩放的元素都使用vw做为单位。不需要缩放的元素使用px做单位。

举个例子。设计师交付的设计稿宽度是750px,设计稿上一个标题的fontSize标注尺寸是32px。(32/750)*100% = 4.27% ,换句话说这个标题的字号占屏幕宽度的占比是4.27%,不管任何屏幕都是如此。4.27% 即 4.27vw。

对于任何需要等比缩放的元素,在写CSS设置样式时直接换算成vw即可,尺寸 = 100vw*设计稿标注大小/设计稿宽度。

2. 适配代码

假设设计稿尺寸是750px,页面有一个按钮,按钮文字标注大小28px,按钮高度标注为48px,宽度为120px,边框为1px不缩放。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    .button {
      width: 16vw;/*  100vw*120/750  */
      font-size: 3.73vw;/*  100vw*28/750  */
      line-height: 6.4vw;/*  100vw*48/750  */
      border: 1px solid #000;/*不需要缩放的部分用px*/
      text-align: center;
    }
  </style>
</head>
<body>
  <div class="button">按钮</div>
</body>
</html>

在写样式时会发现,虽然不用写JS做适配,但标注尺寸换算为vw又麻烦又不直观。

我们可以在CSS里使用calc来换算换,只不过需要注意新语法的兼容性。

:root {
  --ratio: calc(100vw/750);
}
.button {
  font-size: calc(100vw*28/750);/* 可以直接用calc */
  line-height: calc(100vw*48/750);

  width: calc(120*var(--ratio));/* 也可以用calc配合var使用,IE不支持var */
  border: 1px solid #000;/*不需要缩放的部分用px*/
  text-align: center;
}

在正式的项目里,我们也可以用SCSS,把换算交给预处理器

@function px2vw($px) {
  @return $px * 100vw / 750;
}
.button {
  width: px2vw(120);
  font-size: px2vw(28);
  line-height: px2vw(48);
  border: 1px solid #000;
  text-align: center;
}

3. 适配方案对比

  • 动态REM方案
    • 适配原理稍复杂
    • 需要使用JS
    • 设计稿标注的px换算到CSS的rem计算简单
    • 方案灵活技能实现整体缩放又能实现局部不缩放
  • vw方案
    • 适配原理简单
    • 不需要JS即可适配
    • 设计稿标注的px换算到CSS的vw计算复杂
    • 方案灵活技能实现整体缩放又能实现局部不缩放

1px问题

1. 简述

有几种方法能实现0.5px边框:

  1. 直接设置 border-width: 0.5px;使用方便,但兼容性很差,不推荐使用。
  2. 用阴影代替边框,设置阴影box-shadow: 0 0 0 .5px #000; 使用方便,能正常展示圆角,兼容性一般。
  3. 给容器设置伪元素,设置绝对定位,高度为1px,背景图为线性渐变,一半有颜色,一半透明。视觉上宽度只有0.5px。这种方法适合设置一条边框,没法展示圆角。
  4. 给容器内设置伪元素,设置绝对定位,宽、高是200%,边框是1px,然后使用transform: scale(0.5) 让伪元素缩小原来的一半,这时候伪元素的边框和容器的边缘重合,视觉上宽度只有0.5px。这种方法兼容性最好,4个边框都能一次性设置,能正常展示圆角,推荐使用

2. 代码测试

做移动端开发的时候,如果边框直接设置 1px的宽度,可能视觉上还是太粗无法满足设计师的要求。下面是实现0.5px边框的几种方案。推荐方案4,复杂度中等,扩展性良好,兼容性好。

<div class="box box1"> 1px 边框,作为对比 </div>
<div class="box box2"> 方案1: 直接设置0.5px边框</div>
<div class="box box3"> 方案2: 设置0.5px阴影扩散半径 </div>
<div class="box box4"> 方案3: 使用背景渐变实现1px背景的一半</div>
<div class="box box5"> 方案4: 伪元素2倍尺寸1px边框scale缩小一半</div>
<style>
  .box {
  width: 200px;
  height: 50px;
  border-radius: 10px;
  margin-top: 10px;
}
.box1 {
  border: 1px solid #000;
}
.box2 {
  border: 0.5px solid #000;
}
.box3 {
  box-shadow: 0px 0px 0px 0.5px #000;
}
.box4 {
  position: relative;
}
.box4::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background-image: linear-gradient(0deg, #000 50%, transparent 50%);
}
.box5 {
  position: relative;
}
.box5::after {
  position: absolute;
  bottom: 0;
  z-index: -1;
  width: 200%;
  height: 200%;
  content: "";
  display: block;
  border: 1px solid #000;
  border-radius: 10px;
  transform: scale(0.5);
  transform-origin: left bottom;
}
</style>

上面代码的样式


总结:

以上就是 HTML 中移动端的适配方案,不懂得也可以在评论区里问我,以后会持续发布一些新的功能,敬请关注。
我的其他文章:https://blog.csdn.net/weixin_62897746?type=blog

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

超详细讲解 H5 移动端适配方案 的相关文章

随机推荐

  • [转]出租车轨迹处理(二):时空分析

    接下来就要进行一些简单的分析了 今天的目标是如何对某一感兴趣区域进行出租车数据的时空分析 一 轨迹数据预处理 这一步在上一篇文章中已经有了介绍 步骤无非就是 1 使用pandas读取数据 import pandas as pd import
  • Matlab实现粒子群算法(附上完整仿真代码)

    粒子群算法 Particle Swarm Optimization PSO 是一种群体智能算法 通过模拟自然界中鸟群 鱼群等生物群体的行为 来解决优化问题 在PSO算法中 每个个体被称为粒子 每个粒子的位置表示解空间中的一个解 每个粒子的速
  • AVL树的插入与删除(均为递归实现)

    一 引言 AVL树是带有平衡条件的二叉查找树 这个平衡条件必须要容易保持 而且它必须保证树的深度是O logN 一颗AVL树是其每个节点的左子树和右子树的高度最多差一的二叉查找树 主要介绍插入算法和删除算法 二 AVL树的结点定义 type
  • (二)RK3566 Android11固件烧录

    上一篇 一 RK3566 Android11 系统编译 文章目录 1 固件包烧录步骤 2 固件统一打包 3 固件升级 1 固件包烧录步骤 烧录工具位置 RKTools windows AndroidTool AndroidTool Rele
  • e17 enlightenment 介绍及配置

    为什么要有一个窗口管理器 为什么一定要有一个桌面背景 甚至是标题栏 或是如果把一个应用程序如firefox当成桌面背景行不行 桌面能不能再快一点 我不想把资源浪费在那些用不到的地方 Linux那么多虚拟桌面 为什么我不能在一个桌面全屏运行一
  • python django框架ORM模型及ORM操作数据库 笔记

    ORM模型介绍 随着项目的越来越大 采用写原生SQL的方式在代码中会出现大量的SQL语句 那么问题就出现了 1 SQL语句重复利用率不高 越复杂的SQL语句条件越多 代码越长 会出现很多相近的SQL语句 2 很多SQL语句是在业务逻辑中拼出
  • 深度卷积神经网络中的patch

    转载 https blog csdn net wills798 article details 97974617 在阅读基于深度卷积神经网络的图像识别 分类或检测的文献时经常看到 patch 不是很能理解 后来就总结了一下 通过阅读 pat
  • 【深度学习——点云】PointNet++

    这篇文章发表于NIPS 2017 是在PointNet基础上的工作 论文地址 PointNet Deep Hierarchical Feature Learning on Point Sets in a Metric Space 1 Mot
  • vue实现简单轮播图

    实现思路 将vue的框架封装在function中 在界面刷新时调用 将要轮播的图片存放在data中 还有下面的列表也分别保存在data中的一个数组中 然后每隔一段时间进行自动切换的函数写在methods中 注意函数要调用的话 就要在生命周期
  • 如何fork GitHub上的官方仓库

    在GitHub中 fork表示复制一个仓库到你自己的GitHub账号下 创建一个独立的副本 通过fork操作 你可以在自己的副本中进行修改 改进和实验 而不会影响到原始仓库或其他人的工作 当你fork一个仓库时 GitHub将会为你创建一个
  • Spring Boot(二)SpringBoot是如何启动Spring容器源码

    SpringApplication run 调用SpringApplication run启动springboot应用 1 SpringApplication run Application class args 2 使用自定义Spring
  • 使用R语言绘制散点图

    文章目录 学习目标 学习内容 内容小结 学习目标 我们所采用的学习内容来自B站的Lizongzhang老师的R语言的学习分享 今天学习的主要内容是关于 绘制散点图 学习内容 下面是学习的主要内容 直接上代码 大家可以查看视频 我也的注释也比
  • 求阶乘的三种方法

    方法一 递归算法 include
  • 【手把手带你用pid算法控制电机】——(4)串级PID控制电机

    前言 1 该系列教程是基于stm32f103c8t6最小系统板的hal库开发 用最通俗易懂的方式手把手带你学会使用Pid算法的速度环 位置环以及速度位置串级pid 2 出这一期Pid系列教程的想法是前段时间我参加了一个比赛 要用到串级Pid
  • 第1课:三位一体定位法,让写作事半功倍

    做最懂技术的传播者 最懂传播的工程师 课程内容分析 本课程的目标是 通过对一系列问题的梳理 找到适合自己的输出状态 确定与理想输出状态之间存在的差距 以及采取什么办法 减少差距 知识要点 1 受众需要什么 省时间的内容 收敛 看过就走 教你
  • Netty源码剖析之HashedWheelTimer时间轮

    版本信息 JDK1 8 Netty all 4 1 38 Final 时间轮的介绍 我们知道钟表分为很多块 每时钟滴答一次就往前走一个块 而时间轮就是使用这个思想 如下图 上图总共分为8块 每过100ms就往前走一块 然后周而复始 此时 我
  • HC32L130单片机入坑记

    解决问题的思路 经验就可提高工作效率 1 调试中遇到的问题及解决思路 1 程序debug过程中 进入hardware default中断中无限循环 解决办法 运用断点定位到程序debug出错的具体位置 程序最终执行的位置即为程序出错的位置
  • alook浏览器哪个好 夸克浏览器_夸克(Quark)浏览器的安装和使用

    前面的文章 我们大概介绍了一下夸克浏览器的 本片将着重将一下夸克浏览器的使用 下载安装 去夸克的官方网站下载安装包 上传到手机进行安装 去各大应用商店去下载安装 比如小米手机的小米应用商店 华为的华为应用商店 或者第三方的豌豆荚等应用商店去
  • flex & bison 基础概述

    1 前言 限于作者能力水平 本文可能存在谬误 因此而给读者带来的损失 作者不做任何承诺 2 本文目标 简单介绍 flex 和 bison 的基础使用方法 简要分析 flex bison 生成代码的工作流程 3 flex bison 3 1
  • 超详细讲解 H5 移动端适配方案

    目录 REM适配方案 1 前言 2 原理 3 适配代码 4 总结 vw适配方案 1 原理 2 适配代码 3 适配方案对比 1px问题 1 简述 2 代码测试 总结 REM适配方案 1 前言 设计师交付给前端开发一张宽度为750px的视觉稿