HTML5 移动端自适应方案与踩坑

2023-12-18 16:48

本文主要是介绍HTML5 移动端自适应方案与踩坑,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文链接:blog.sjfkai.com/2019/01/29/…

转载请注明出处

最近刚接触前端开发,接手了一个移动端H5项目。着实体会掉了前端的坑之多,和H5移动端的坑之多多。

如今项目告一段落,在这里做一总结

屏幕自适应方案

介绍方案之前,首先还是交代一下项目背景与需求,毕竟一切方案也不能脱离实际需求。

需求与背景

  • 设备宽度 > 800px, body宽度为800px
  • 320px < 设备宽度 < 800px, 宽度根据设备宽度自适应
  • 设备宽度 > 320px, body宽度为320px
  • 大部分字体不随宽度变化而缩放
  • 设计图宽度:1080px

自适应方案

关于自适应方案,google一搜就会有很多结果,但是总的来说个人认为最有用的还是手淘的大漠写的一系列文章,后面会给出原文链接。总的来说主流的方案有remvh两种。

REM(flexible)

rem(font size of the root element)是指相对于根元素的字体大小的单位。简单的说它就是一个相对单位。看到rem大家一定会想起em单位,em(font size of the element)是指相对于父元素的字体大小的单位。它们之间其实很相似,只不过一个计算的规则是依赖根元素一个是依赖父元素计算。

所以简而言之,就是根据屏幕宽度设置 html 标签的 font-size。 再在布局时使用 rem 单位来布局,就可以达到自适应的目的。

使用此方案,可以借助手淘的开源项目lib-flexible。它可以自定帮你设置html 标签的 font-size等。将1rem设置为屏幕的1/10

关于 rem 方案,大漠老师在使用Flexible实现手淘H5页面的终端适配中进行了详细的介绍。建议大家阅读一下。

如你所见,大漠老师也在近期对文正进行了更新,建议大家使用更方便的 vw 方案。

VW

vw 是视口宽度的1/100,用 vw 来做自适应再合适不过了。

比如如果你的设计图是 750px 的宽度。 对于 75px 的元素就可以设置为 1vw。 这样在宽度为 375px 的手机上的表现就是37.5px

当然,如果我们把每个 px 标注都手动转换的话,那也是很大的工作量, postcss-px-to-viewport可以自定帮你转换为 vw。 你只需要在配置时指定设计图宽度就可以了。

同样,强烈建议你去阅读以下大漠老师关于 vw 布局的文章 再聊移动端页面的适配

我的方案 vw + rem

vw 虽好,可惜却无法满足我的需求。因为 vw 是整个视口宽度的1%,如果单纯采用 vw 方案,是无法限制 body 最大、最小宽度的。

于是我便采用了 vw + rem。 如果屏幕宽度在需要自适应的宽度之内,则将html 标签的 font-size设置为 10vw。如果屏幕宽度超过最大或最小限制的话。则将html 标签的 font-size设置为固定值。类似于lib-flexible,我们将1rem设为了屏幕的1/10

具体 css 如下:

html {height: 100%;font-size: 10vw;
}
body {font-size: 16px;width: 100%;height: 100%;margin: 0 auto;
}@media screen and (max-width: 320px) {html{font-size: 32px;}body{min-width: 320px;}
}
@media screen and (min-width: 800px) {html{font-size: 80px;}body{max-width: 800px;}
}
复制代码

当然,这样在布局时,我们就需要使用rem单位来布局了。 当然设计图标注pxrem单位同样有现成的工具。博主使用的是postcss-pxtorem。

最终的效果:

 

效果图

 

 

以上介绍的适配方案,基本上就可以满足大部分的需求了。 下面我们来聊一聊我都遇到了哪些坑。

小数像素问题

由于我们的方案,所有元素根据屏幕宽度来自适应。因而很难保证转换后的像素为整数像素。

在未接触前端,或者说H5开发之前并没有认真考虑过小数像素的问题,最初以为就是在可现实的精度上四舍五入。真正开发时发现并不是这样的。

比如下面这个例子,同样的像素值表现就不一样:在线实例

 

 

 

IOSmacOS设备最小像素好像支持到了0.5px,所以上面的例子在苹果设备上表现并不是很明显。

但是毕竟大部分设备还是Androidwindows系统。

那么,到底浏览器是如何处理小数像素的呢? rem 产生的小数像素问题 这篇文章给出了答案:

浏览器在渲染时所做的舍入处理只是应用在元素的渲染尺寸上,其真实占据的空间依旧是原始大小。
也就是说如果一个元素尺寸是 0.625px,那么其渲染尺寸应该是 1px,空出的 0.375px 空间由其临近的元素填充;同样道理,如果一个元素尺寸是 0.375px,其渲染尺寸就应该是 0,但是其会占据临近元素 0.375px 的空间。
复制代码

那么在我们的方案里会出现什么问题呢?

  1. 缩放到低于1px的元素会时隐时现
  2. 两个同样宽度的元素因为各自周围的元素宽度不同,导致两元素相差1px
  3. 宽高相同的正方形,长宽不相等了
  4. border-radius: 50% 画的圆不圆了

对于第一个问题,一般都会出现在标注为1px的地方。所以大部分的插件 postcss-pxtorem 或者 postcss-px-to-viewport 都提供了最小转换像素的选项。 我们只要指定最小转换像素,对于比较小的像素(如:1px),就不转换为remvw了。当然1px在视网膜屏同样存在过粗的问题,我们在之后会讨论。

对于剩下的几个问题,目前本人也没找到特别好的办法,毕竟很多地方相差1px是可以接受的。只有一些比较小的元素会表现的比较明显,本人的解决办法是不通过插件自动转换为remvw,而是通过js根据设备宽度,计算出该元素在该设备下实际的px。取整后动态地设置到元素的style上。这样就不会出现上述问题了。

如果各位有更好的解决方案的话。欢迎留言讨论。

1px问题

由于上面小数像素的问题,我们并没有对1px的元素进行转换,所以对于750px的设计图上1px的细线,在屏幕宽度为375pxiphone6上依旧为1px,按比例应该是0.5px。所以设计同学会问:“为什么这条细线变粗了?” 我们也很无奈啊,因为0.5px显不出来啊……

但是转念一想,对于DPR=2甚至更高的设备,1px是由多个物理像素渲染的,其实是可以显示更细的线的。那么这样才能画出更细的线呢?

大漠老师又出场了,《再谈Retina下1px的解决方案》中给出了几种方案:

  1. viewport放大为device-widthdpr倍数,然后缩小1/dpr倍显示
  2. border-image设为一个一半透明一半显示的图片,以达到将边框一分为二的目的
  3. 同样是上面的原理,但是使用svg绘制图片
  4. 媒体查询配合伪元素,为伪元素设置1px的边框,然后缩小1/dpr倍显示

以上方案各有各的特点,2、3两个方案画出来的其实是0.5px,而1、4两个方案画出来的更接近物理像素的1px

cursor:pointer 元素点击背景变色的问题

对于添加了 cursor:pointer 属性的元素,在移动端点击时,背景会高亮。

为元素添加 -webkit-tap-highlight-color: transparent; 属性可以隐藏背景高亮。

Android浏览器下line-height垂直居中偏离的问题

我们常用的垂直居中方式就是使用line-height,但是这种方法在Android设备下并不能完全居中。

具体原因是因为Android中文字体排版的问题,可以参考 知乎:Android浏览器下line-height垂直居中为什么会偏离?

通过设置字体,确实能够解决一部分偏离的问题。但仍然会出现一些略微偏离的情况,据说与行高奇数偶数有关。不过已经不太容易分辨了,如果还是不能接受的话建议通过设置上下padding的方式进行垂直居中,再根据具体情况进行微调。

参考文章

  • 使用Flexible实现手淘H5页面的终端适配
  • 再聊移动端页面的适配
  • rem 产生的小数像素问题
  • 再谈Retina下1px的解决方案
  • Android浏览器下line-height垂直居中为什么会偏离?


作者:sjfkai
链接:https://juejin.im/post/5c8870c1e51d453ce668cc7f
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

这篇关于HTML5 移动端自适应方案与踩坑的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

MySQL 迁移至 Doris 最佳实践方案(最新整理)

《MySQL迁移至Doris最佳实践方案(最新整理)》本文将深入剖析三种经过实践验证的MySQL迁移至Doris的最佳方案,涵盖全量迁移、增量同步、混合迁移以及基于CDC(ChangeData... 目录一、China编程JDBC Catalog 联邦查询方案(适合跨库实时查询)1. 方案概述2. 环境要求3.

SpringBoot3.X 整合 MinIO 存储原生方案

《SpringBoot3.X整合MinIO存储原生方案》本文详细介绍了SpringBoot3.X整合MinIO的原生方案,从环境搭建到核心功能实现,涵盖了文件上传、下载、删除等常用操作,并补充了... 目录SpringBoot3.X整合MinIO存储原生方案:从环境搭建到实战开发一、前言:为什么选择MinI

Knife4j+Axios+Redis前后端分离架构下的 API 管理与会话方案(最新推荐)

《Knife4j+Axios+Redis前后端分离架构下的API管理与会话方案(最新推荐)》本文主要介绍了Swagger与Knife4j的配置要点、前后端对接方法以及分布式Session实现原理,... 目录一、Swagger 与 Knife4j 的深度理解及配置要点Knife4j 配置关键要点1.Spri

SQLite3 在嵌入式C环境中存储音频/视频文件的最优方案

《SQLite3在嵌入式C环境中存储音频/视频文件的最优方案》本文探讨了SQLite3在嵌入式C环境中存储音视频文件的优化方案,推荐采用文件路径存储结合元数据管理,兼顾效率与资源限制,小文件可使用B... 目录SQLite3 在嵌入式C环境中存储音频/视频文件的专业方案一、存储策略选择1. 直接存储 vs

前端如何通过nginx访问本地端口

《前端如何通过nginx访问本地端口》:本文主要介绍前端如何通过nginx访问本地端口的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、nginx安装1、下载(1)下载地址(2)系统选择(3)版本选择2、安装部署(1)解压(2)配置文件修改(3)启动(4)

HTML中meta标签的常见使用案例(示例详解)

《HTML中meta标签的常见使用案例(示例详解)》HTMLmeta标签用于提供文档元数据,涵盖字符编码、SEO优化、社交媒体集成、移动设备适配、浏览器控制及安全隐私设置,优化页面显示与搜索引擎索引... 目录html中meta标签的常见使用案例一、基础功能二、搜索引擎优化(seo)三、社交媒体集成四、移动

HTML input 标签示例详解

《HTMLinput标签示例详解》input标签主要用于接收用户的输入,随type属性值的不同,变换其具体功能,本文通过实例图文并茂的形式给大家介绍HTMLinput标签,感兴趣的朋友一... 目录通用属性输入框单行文本输入框 text密码输入框 password数字输入框 number电子邮件输入编程框

HTML img标签和超链接标签详细介绍

《HTMLimg标签和超链接标签详细介绍》:本文主要介绍了HTML中img标签的使用,包括src属性(指定图片路径)、相对/绝对路径区别、alt替代文本、title提示、宽高控制及边框设置等,详细内容请阅读本文,希望能对你有所帮助... 目录img 标签src 属性alt 属性title 属性width/h

CSS3打造的现代交互式登录界面详细实现过程

《CSS3打造的现代交互式登录界面详细实现过程》本文介绍CSS3和jQuery在登录界面设计中的应用,涵盖动画、选择器、自定义字体及盒模型技术,提升界面美观与交互性,同时优化性能和可访问性,感兴趣的朋... 目录1. css3用户登录界面设计概述1.1 用户界面设计的重要性1.2 CSS3的新特性与优势1.

HTML5 中的<button>标签用法和特征

《HTML5中的<button>标签用法和特征》在HTML5中,button标签用于定义一个可点击的按钮,它是创建交互式网页的重要元素之一,本文将深入解析HTML5中的button标签,详细介绍其属... 目录引言<button> 标签的基本用法<button> 标签的属性typevaluedisabled