h5移动端屏幕适配方案(rem、vw)

2024-05-04 20:58
文章标签 移动 方案 屏幕 h5 适配 rem vw

本文主要是介绍h5移动端屏幕适配方案(rem、vw),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、概述

移动端屏幕大小不一,要使网页能自适应不同尺寸的手机屏幕,而且还要尽可能开发便捷,目前使用最多的还是rem大法,相对比较成熟,而新兴的vw方案也可以一试。
本文主要介绍rem和vw两种方案的使用配置方式。

2、meta设置

首先移动端要设置好视口,使视口的宽度等于设备屏幕宽度,这样浏览器识别后就认为该网页是移动端网页,同时也就不再有点击300ms延迟的问题了:

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

3、rem方案

(1)原理

css中rem单位的计算是基于根字体大小,也就是html标签元素的font-size,未设置font-size时默认字体大小是16px,假设根字体大小就是16px,那比如2rem就等于2 * 16 = 32 px。
如果所有涉及尺寸的css单位都用rem来写,那实际尺寸就取决于根字体大小是多少了,那如果根据手机屏幕宽度和设计图宽度的比例去动态改变根字体大小,就能实现实际屏幕呈现出和设计图一致的效果。

(2)js基础封装:动态计算根字体大小

  • 首先需要定义下设计图尺寸(宽度)和基准值,基准值即1rem等于多少px,设计图尺寸也确定下来,就表示在该尺寸下根字体大小为该基准值。
  • 根据上述rem原理就能得出一个公式:实际屏幕宽度 / 设计图尺寸 = 实际根字体大小 / 基准值
  • 将上述公式调下顺序:要计算的根字体大小值 = 实际屏幕宽度 / 设计图尺寸 * 基准值
  • 示例代码:
var sizeUI = 375 // 定义设计图尺寸
var remBase = 37.5 // 定义基准值
var docEl = document.documentElement // 获取html元素setRemUnit() // 执行函数function setRemUnit () {var docFontSize = docEl.clientWidth / sizeUI * remBase // 计算得到根字体大小docEl.style.fontSize = docFontSize + 'px' // 设置根字体大小
}
  • 如上代码,设计图尺寸设为375是为了方便chrome调试,毕竟chrome调试下iphoneX默认宽度就是375,查看尺寸大小时方便,基准值设为37.5,这样也能适配vant UI;
  • 上述代码要在页面一打开时就加载,然后开发时写元素尺寸就按照375设计图下该元素的px尺寸除以基准值37.5得到的rem值。

(3)js封装优化:重置网页默认大小

  • css中字体样式是可以继承的,元素未设置font-size时字体大小是从父级元素继承,层层网上找,如果找到根元素(html)也没有设置font-size时就取默认字体大小,默认是16px。
  • 在用rem方案时会给根元素设置字体大小,这个值一般都很大,而给body元素设置下字体大小为16px就能实现重置的效果。
  • 只需要在上述封装的代码 setRemUnit 函数里末尾加一行:
document.querySelector('body').style.fontSize = 16 / docFontSize + 'rem'

(4)js封装优化:响应屏幕尺寸的变化

  • 监听到屏幕尺寸改变时重新设置根字体大小
  • 直接上代码:
window.addEventListener('resize', setRemUnit) // 触发示例:屏幕旋转
window.addEventListener('pageshow', function (e) { // 触发示例:有页面缓存功能的浏览器的前进后退if (e.persisted) setRemUnit()
})

(5)js封装优化:个别机型rem计算不准的兼容

  • rem方案确实存在个别机型的兼容性问题,常见于华为手机(大骂!!!),个别机型用rem计算出来的尺寸有偏差,导致页面两边留白或有横向滚动,还有些机型在改变手机系统默认字体大小时也会出现类似问题,这也是rem方案被人诟病的点,但其实这一点是可以做兼容处理的。
  • 原因:这种现象从网页里体现出的原因是根字体元素实际字体大小和设置的字体大小不一致,有几px的偏差。
  • 解决方法:根字体元素实际字体大小可以通过getComputedStyle获取到,然后和设置的字体大小进行比较,高了就让设置的字体大小加1,低了就减1,重复执行,直到两者差距值不超过1就认为差不多值合适了。
  • 代码:
var docEl = document.documentElementfunction handleRemAdapt () {var currentFontSize = parseInt(docEl.style.fontSize)var temp = currentFontSizefor (var i = 0; i < 100; i++) { // 只遍历100次,够用了var realFontSize = parseInt(window.getComputedStyle(docEl).fontSize)var differ = realFontSize - currentFontSizeif (Math.abs(differ) >= 1) {if (differ > 0) {temp--} else {temp++}docEl.style.fontSize = temp + 'px'} else {break}}
}

(6)完整js封装及项目中引入

  • 完整js代码 flexible.js
;(function (window, document) {var sizeUI = 375 // 定义设计图尺寸var remBase = 37.5 // 定义基准值var docEl = document.documentElementvar bodyEl = document.querySelector('body')setRemUnit()window.addEventListener('resize', setRemUnit)window.addEventListener('pageshow', function (e) {if (e.persisted) setRemUnit()})function setRemUnit () {var docFontSize = docEl.clientWidth / sizeUI * remBasedocEl.style.fontSize = docFontSize + 'px'bodyEl.style.fontSize = 16 / docFontSize + 'rem'handleRemAdapt()}function handleRemAdapt () {var currentFontSize = parseInt(docEl.style.fontSize)var temp = currentFontSizefor (var i = 0; i < 100; i++) {var realFontSize = parseInt(window.getComputedStyle(docEl).fontSize)var differ = realFontSize - currentFontSizeif (Math.abs(differ) >= 1) {if (differ > 0) {temp--} else {temp++}docEl.style.fontSize = temp + 'px'} else {break}}}
})(window, document)
  • 普通html页面中建议在head标签内引入该js:
<head><script src="./flexible.js"></script>
</head>
  • spa单页面项目中直接在项目入口文件里引入即可:
import './flexible.js'

(7)webpack中配置px自动转rem

对于webpack项目,利用插件可以做到webpack编译打包时自动将px单位转rem,这样开发时只需要写px不用再计算,非常方便。

  • 首先项目中需要先集成插件postcss,vue-cli和create-react-app创建的项目已默认集成可以忽略。
  • 然后再集成插件:postcss-plugin-px2rem 官方地址
  • 安装依赖
npm i postcss-plugin-px2rem -D
  • 然后在postcss配置文件(例如postcss.config.js)里进行配置:
module.exports = {plugins: {autoprefixer: {},'postcss-plugin-px2rem': {rootValue: 37.5, // 基准值,和flexible.js里的保持一致selectorBlackList: ['noRem'],minPixelValue: 2}}
}
  • 需要注意的是,这种方式只能转换样式文件里px单位,比如css、less、vue页面的style标签等,而dom结构里的行内样式(style属性)以及通过js代码动态设置的单位不会自动转换,仍然需要自己手动处理(将px单位处以37.5换算成rem单位即可)。

4、vw方案

如果rem方案使用的得心应手了,再看vw方案就很简单了,vw单位在移动端兼容性已经没问题了,其他方面还需要在项目中实践检验。

(1)原理

vw是视口单位,是视口宽度等分100份后所占的份数,1vw就相当于屏幕宽度的1%,所以使用vw单位在不同屏幕尺寸下能天然的自适应。

(2)使用

vw方案相比rem方案无需封装引入js文件,将设计图尺寸下的元素大小转换为vw就能直接使用,简单很多。

(3)webpack中配置px自动转vw

webpack项目中可以 利用插件进行自动转换,和上述px自动转rem类似。

  • 同样需要依赖postcss,脚手架创建的项目已默认集成postcss可以忽略此条。
  • 然后引入插件:postcss-px-to-viewport 官方地址
  • 安装依赖:
npm i -D postcss-px-to-viewport
  • 配置postcss.config.js:
module.exports = {plugins: {autoprefixer: {},'postcss-px-to-viewport': {viewportWidth: 375, // 设计图尺寸minPixelValue: 2}}
}
  • 同样的,只转换样式文件里的单位,行内样式里及js里的px单位不会自动转换,需手动处理。

这篇关于h5移动端屏幕适配方案(rem、vw)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/960066

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

高效+灵活,万博智云全球发布AWS无代理跨云容灾方案!

摘要 近日,万博智云推出了基于AWS的无代理跨云容灾解决方案,并与拉丁美洲,中东,亚洲的合作伙伴面向全球开展了联合发布。这一方案以AWS应用环境为基础,将HyperBDR平台的高效、灵活和成本效益优势与无代理功能相结合,为全球企业带来实现了更便捷、经济的数据保护。 一、全球联合发布 9月2日,万博智云CEO Michael Wong在线上平台发布AWS无代理跨云容灾解决方案的阐述视频,介绍了

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

JavaFX应用更新检测功能(在线自动更新方案)

JavaFX开发的桌面应用属于C端,一般来说需要版本检测和自动更新功能,这里记录一下一种版本检测和自动更新的方法。 1. 整体方案 JavaFX.应用版本检测、自动更新主要涉及一下步骤: 读取本地应用版本拉取远程版本并比较两个版本如果需要升级,那么拉取更新历史弹出升级控制窗口用户选择升级时,拉取升级包解压,重启应用用户选择忽略时,本地版本标志为忽略版本用户选择取消时,隐藏升级控制窗口 2.

我在移动打工的日志

客户:给我搞一下录音 我:不会。不在服务范围。 客户:是不想吧 我:笑嘻嘻(气笑) 客户:小姑娘明明会,却欺负老人 我:笑嘻嘻 客户:那我交话费 我:手机号 客户:给我搞录音 我:不会。不懂。没搞过。 客户:那我交话费 我:手机号。这是电信的啊!!我这是中国移动!! 客户:我不管,我要充话费,充话费是你们的 我:可是这是移动!!中国移动!! 客户:我这是手机号 我:那又如何,这是移动!你是电信!!

如何选择SDR无线图传方案

在开源软件定义无线电(SDR)领域,有几个项目提供了无线图传的解决方案。以下是一些开源SDR无线图传方案: 1. **OpenHD**:这是一个远程高清数字图像传输的开源解决方案,它使用SDR技术来实现高清视频的无线传输。OpenHD项目提供了一个完整的工具链,包括发射器和接收器的硬件设计以及相应的软件。 2. **USRP(Universal Software Radio Periphera

EasyPlayer.js网页H5 Web js播放器能力合集

最近遇到一个需求,要求做一款播放器,发现能力上跟EasyPlayer.js基本一致,满足要求: 需求 功性能 分类 需求描述 功能 预览 分屏模式 单分屏(单屏/全屏) 多分屏(2*2) 多分屏(3*3) 多分屏(4*4) 播放控制 播放(单个或全部) 暂停(暂停时展示最后一帧画面) 停止(单个或全部) 声音控制(开关/音量调节) 主辅码流切换 辅助功能 屏

用Unity2D制作一个人物,实现移动、跳起、人物静止和动起来时的动画:中(人物移动、跳起、静止动作)

上回我们学到创建一个地形和一个人物,今天我们实现一下人物实现移动和跳起,依次点击,我们准备创建一个C#文件 创建好我们点击进去,就会跳转到我们的Vision Studio,然后输入这些代码 using UnityEngine;public class Move : MonoBehaviour // 定义一个名为Move的类,继承自MonoBehaviour{private Rigidbo

MyBatis 切换不同的类型数据库方案

下属案例例当前结合SpringBoot 配置进行讲解。 背景: 实现一个工程里面在部署阶段支持切换不同类型数据库支持。 方案一 数据源配置 关键代码(是什么数据库,该怎么配就怎么配) spring:datasource:name: test# 使用druid数据源type: com.alibaba.druid.pool.DruidDataSource# @需要修改 数据库连接及驱动u

简单的角色响应鼠标而移动

actor类 //处理移动距离,核心是找到角色坐标在世界坐标的向量的投影(x,y,z),然后在世界坐标中合成,此CC是在地面行走,所以Y轴投影始终置为0; using UnityEngine; using System.Collections; public class actor : MonoBehaviour { public float speed=0.1f; CharacterCo