大厂实战出发,总结H5容器适配方案,不看你就亏了

2,698 阅读7分钟

引言

PC适配, IE一直是前端程序员头大的问题, 由于最初网页标准不统一, 各大厂商都有自己实现浏览器的一套标准, 这就导致很多的公共API不能够实现全浏览器平台, 以IE为主. 曾经IE 可以说是FEE最厌恶的浏览器.

逃离的PC端, 当你拥抱移动端时候, 你会发现, 又陷入另外一个坑, 那就是适配各种不同分辨率, 不同尺寸屏幕的手机. 本文将对现在主流移动端适配方案进行一个对比。

基本概念介绍

设备像素 / 物理像素 (physical pixels)
是指屏幕的实际物理像素点, 比如 iPhone6 Plus 是 1920*1080 的像素分辨率, 那么代表它纵向有 1920 个物理像素点, 横向有 1080 个物理像素点.

CSS 像素(css pixel) / 密度独立像素(density independent pixels - dip)

CSS 像素是 web 编程中的概念, 是抽象的, 不是实际存在的. 它是独立于设备用于逻辑上衡量像素的单位, 所以又叫密度独立像素. dip 有时候也缩写为 dp.

屏幕尺寸

指屏幕的对角线长度, 单位是英寸(inch), 1 英寸 = 2.54 厘米. 常见屏幕尺寸有 5.0、5.5 和 6.0 等.

屏幕像素密度(pixels per inch - ppi)

指屏幕上每英寸可以显示的物理像素点的数量. 比如 iPhone6 Plus 是 5.5 英寸, 分辨率(也就是物理像素)是 1920*1080 像素, 那么它的 ppi = √(19202+10802) / 5.5 ≈ 401ppi. 也就是说它每英寸可以显示 440 个物理像素点.

设备像素比

指物理像素和密度独立像素的比值. window.devicePixelRatio = 物理像素/dip.可以通过window.devicePixelRatio 获得, 该属性被所有WebKit浏览器以及Opera所支持。

基本视窗概念

1.layout viewport 网页的所有内容, 可以全部或者部分展示给用户
2.visual viewport 当前显示给用户内容的窗口, 可以拖动或者方法缩小网页
3.idea viewport 即页面绘制区域可以完美适配设备宽度的视口大小, 不需要出现滚动条即可正常查看网站的所有内容, 且文字图片清晰

ViewPort 原理

利用viewport 的width属性设置layout viewport的大小, 并利用initial-scale属性设置layout viewport的缩放比例, 使layout viewport 与visual viewport的宽度一致: 用户无需进行缩放

ViewPort 值/含义

含义
width 设置layout viewport的宽度,为一个正整数,或字符串"width-device"
initial-scale 设置页面的初始缩放值,为一个数字,可以带小数
minimum-scale 允许用户的最小缩放值,为一个数字,可以带小数
maximum-scale 允许用户的最大缩放值,为一个数字,可以带小数
height 设置layout viewport 的高度,这个属性对我们并不重要,很少使用
user-scalable 是否允许用户进行缩放,值为"no"或"yes", no 代表不允许,yes代表允许

现有的H5适配方案

  1. css3媒体查询方式容器适配 媒体查询,需要你通过媒体查询来根据不同的屏幕宽度进行不同的css编写,也就是说会存在多套css
@media screen and (max-width: 320px){
    ....适配iphone4的css样式
}
@media screen and (max-width: 375px){
     ....适配iphone6/7/8的css样式
}
@media screen and (max-width: 414px){
    ....适配iphone6/7/8 plus的css样式
}
......
  1. 百分比布局容器适配 给元素设定不同的百分比占比,这样在不同的大小的容器下面就能够呈现对应的尺寸大小,但是有几个需要注意的点 元素的width/height是相对于直接父元素的width/height进行计算的
    元素的margin/padding是相对于直接父元素的width进行计算的
    元素的border-radius等是根据自身宽度进行计算的

  2. rem相对单位容器适配
    rem单位:rem是一个只相对于浏览器的根元素(HTML元素)的font-size的来确定的单位。默认情况下,html元素的font-size为12px
    通过rem来实现适配:rem单位都是相对于根元素html的font-size来决定大小的,根元素的font-size相当于提供了一个基准,当页面的宽度发生变化时,只需要改变font-size的值,那么以rem为固定单位的元素的大小也会发生响应的变化。需要先动态设置html根元素的font-size,再计算出其他页面元素以rem为固定单位的值

var deviceWidth = document.documentElement.clientWidth;
deviceWidth = deviceWidth < 320 ? 320 : deviceWidth > 640 ? 640 : deviceWidth;
document.documentElement.style.fontSize = deviceWidth / 7.5 + 'px';
  1. vh/vm视口单位容器适配 视口单位相对于视口的高度和宽度,而不是父元素的(CSS百分比是相对于包含它的最近的父元素的高度和宽度)。1vh 等于1/100的视口高度,1vw 等于1/100的视口宽度。(有没有感觉到跟百分比相似,只是百分比是对比父元素的宽高,视口单位对比的是视口的宽高)

各厂解决方案(自己调研, 不一定准确)

以css长度单位作为类型划分标准 && 考虑对比图文类H5移动端布局,是否与UX关联选型? 1.px方案(媒体查询):传统的媒体查询响应式布局(腾讯新闻,知乎,点评,头条) 示例:

    @media screen and (max-width:480px){body{background:red;}}/宽度小于480px时 绿色/
    @media screen and (min-width:980px){body{background:yellow;}}/宽度大于980px时 红色/

2.viewport(不缩放)+rem方案:用与根元素 font-size 相关联的 rem 单位定义元素宽高,这样就等于使用了 rem 间接与页面宽度产生联系,确定了比例,从而实现等比缩放。(马蜂窝,小米,小红书) viewport(缩放)+rem方案 示例:

    <meta name="viewport" id="vp" content="viewport-fit=cover,initial-scale=1,minimum-scale=1,maximum-scale=1,width=device-width,user-scalable=no"/>
    html{
    	font-size:100px
    }
    .container{
    	width:3.5rem;
    	height:5rem
    }

3.vw+rem方案:元素布局上依然使用rem单位,没有缩放viewport, html元素的font-size则使用vw + px fallback的形式(京东,网易,饿了么)
示例:

    <meta name="viewport" id="vp" content="viewport-fit=cover,initial-scale=1,minimum-scale=1,maximum-scale=1,width=device-width,user-scalable=no"/>
    html{
    	font-size:100px;
    	font-size:26.66666667vw;
    }

    @media screen and (min-width:375px){
        html{
        	font-size:100px;
        	font-size:26.66666667vw
        }
    }

    @media screen and (max-width:320px){
        html{
        	font-size:90px;
        	font-size:26.66666667vw
        }
    }

    .container{
    	width:3.5rem;
    	height:5rem
    }

利弊分析

1.px方案(媒体查询):
优点: 简洁易懂的css语句,不用考虑冗杂的百分比,不用担心页面元素会拉伸变形,可以展示出更多的内容,营造更好的体验,更加符合人们的阅读习习惯。
缺点: 工作量大,代码量多。 代码更新维护较困难。
待续......


2.viewport+rem方案:
优点: 比较成熟的解决方案了,出镜率也较高,只需在html中对font-size进行字体设置即可适配多平台。
缺点: 需要进行计算进行单位换算,引入某些hotcss,带来性能上肯能降低的问题。
font-size设置不能够很好的进行完全适配。可以进行媒体查询(不连续,不能完全实现对所有设备的布局规范统一),进行js动态更改html字体(没有直接写媒体查询体验好)
在奇葩dpr设备上会出现错乱,例如:华为的高端机型,用rem布局会出现错乱
待续.....


3.vw+rem方案:
优点: 现有的rem方案的改动都不会很大,兼容性问题得到了保证
缺点: 需要进行计算进行单位换算,带来性能上肯能降低的问题。尚存在不支持vw的浏览器,需要做兼容 待续......

针对于图文类H5最佳实践(iqiyi漫画H5)

1.media+rem+vw方案(思考方向:代码开发维护,用户体验)
(1). 利用viewport 固定layout viewport的宽度为devicewidth
(2). 利用vw根据屏幕宽度设置html的font-size,并且利用media进行不同设备的兼容,利用px做不支持vw的浏览器兼容
(3). 针对于不同页面特定的点,可以进行单独media,进行一些定制化的px方案覆盖,来达到更加完美的效果 待续......