双11上云86元/年css
原文连接:blog.sjfkai.com/2019/01/29/…html
转载请注明出处前端
最近刚接触前端开发,接手了一个移动端H5项目。着实体会掉了前端的坑之多,和H5移动端的坑之多多。git
现在项目告一段落,在这里作一总结github
介绍方案以前,首先仍是交代一下项目背景与需求,毕竟一切方案也不能脱离实际需求。web
关于自适应方案,google一搜就会有不少结果,可是总的来讲我的认为最有用的仍是手淘的大漠写的一系列文章,后面会给出原文连接。总的来讲主流的方案有rem
和vh
两种。npm
rem
(font size of the root element)是指相对于根元素的字体大小的单位。简单的说它就是一个相对单位。看到rem
你们必定会想起em
单位,em
(font size of the element)是指相对于父元素的字体大小的单位。它们之间其实很类似,只不过一个计算的规则是依赖根元素一个是依赖父元素计算。windows
因此简而言之,就是根据屏幕宽度设置 html
标签的 font-size
。 再在布局时使用 rem
单位来布局,就能够达到自适应的目的。浏览器
使用此方案,能够借助手淘的开源项目lib-flexible。它能够自动帮你设置html
标签的 font-size
等。将1rem
设置为屏幕的1/10
。iphone
关于 rem
方案,大漠老师在使用Flexible实现手淘H5页面的终端适配中进行了详细的介绍。建议你们阅读一下。
如你所见,大漠老师也在近期对文正进行了更新,建议你们使用更方便的 vw
方案。
vw
是视口宽度的1/100,用 vw
来作自适应再合适不过了。
好比若是你的设计图是 750px
的宽度。 对于 75px
的元素就能够设置为 10vw
。 这样在宽度为 375px
的手机上的表现就是37.5px
。
固然,若是咱们把每一个 px
标注都手动转换的话,那也是很大的工做量, postcss-px-to-viewport能够自动帮你转换为 vw
。 你只须要在配置时指定设计图宽度就能够了。
一样,强烈建议你去阅读如下大漠老师关于 vw
布局的文章 再聊移动端页面的适配
vw
虽好,惋惜却没法知足个人需求。由于 vw
是整个视口宽度的1%,若是单纯采用 vw
方案,是没法限制 body
最大、最小宽度的。
因而我便采用了 vw
+ rem
。 若是屏幕宽度在须要自适应的宽度以内,则将html
标签的 font-size
设置为 10vw
。若是屏幕宽度超过最大或最小限制的话。则将html
标签的 font-size
设置为固定值。相似于lib-flexible
,将1rem
设为了 body 宽度的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
单位来布局了。 设计图标注 px
转 rem
单位一样也有现成的工具。博主使用的是postcss-pxtorem。
最终的效果:
以上介绍的适配方案,基本上就能够知足大部分的需求了。 下面咱们来聊一聊我都遇到了哪些坑。
因为咱们的方案,全部元素根据屏幕宽度来自适应。于是很难保证转换后的像素为整数像素。
在未接触前端,或者说H5开发以前并无认真考虑太小数像素的问题,最初觉得就是在可现实的精度上四舍五入。真正开发时发现并非这样的。
好比下面这个例子,一样的像素值表现就不同:在线实例
IOS
、macOS
设备最小像素好像支持到了0.5px,因此上面的例子在苹果设备上表现并非很明显。
可是毕竟大部分设备仍是Android
和windows
系统。
那么,到底浏览器是如何处理小数像素的呢? rem 产生的小数像素问题 这篇文章给出了答案:
浏览器在渲染时所作的舍入处理只是应用在元素的渲染尺寸上,其真实占据的空间依旧是原始大小。
也就是说若是一个元素尺寸是 0.625px,那么其渲染尺寸应该是 1px,空出的 0.375px 空间由其临近的元素填充;一样道理,若是一个元素尺寸是 0.375px,其渲染尺寸就应该是 0,可是其会占据临近元素 0.375px 的空间。
复制代码
那么在咱们的方案里会出现什么问题呢?
border-radius: 50%
画的圆不圆了对于第一个问题,通常都会出如今标注为1px
的地方。因此大部分的插件 postcss-pxtorem 或者 postcss-px-to-viewport 都提供了最小转换像素的选项。 咱们只要指定最小转换像素,对于比较小的像素(如:1px
),就不转换为rem
或vw
了。固然1px
在视网膜屏一样存在过粗的问题,咱们在以后会讨论。
对于剩下的几个问题,目前本人也没找到特别好的办法,毕竟不少地方相差1px
是能够接受的。只有一些比较小的元素会表现的比较明显,本人的解决办法是不经过插件自动转换为rem
或vw
,而是经过js
根据设备宽度,计算出该元素在该设备下实际的px
。取整后动态地设置到元素的style
上。这样就不会出现上述问题了。
若是各位有更好的解决方案的话。欢迎留言讨论。
因为上面小数像素的问题,咱们并无对1px
的元素进行转换,因此对于750px
的设计图上1px
的细线,在屏幕宽度为375px
的iphone6
上依旧为1px
,按比例应该是0.5px
。因此设计同窗会问:“为何这条细线变粗了?” 咱们也很无奈啊,由于0.5px
显不出来啊……
可是转念一想,对于DPR=2
甚至更高的设备,1px
是由多个物理像素渲染的,实际上是能够显示更细的线的。那么这样才能画出更细的线呢?
大漠老师又出场了,《再谈Retina下1px的解决方案》中给出了几种方案:
viewport
放大为device-width
的dpr
倍数,而后缩小1/dpr
倍显示border-image
设为一个一半透明一半显示的图片,以达到将边框一分为二的目的svg
绘制图片1px
的边框,而后缩小1/dpr
倍显示以上方案各有各的特色,二、3两个方案画出来的实际上是0.5px
,而一、4两个方案画出来的更接近物理像素的1px
对于添加了 cursor:pointer
属性的元素,在移动端点击时,背景会高亮。
为元素添加 -webkit-tap-highlight-color: transparent;
属性能够隐藏背景高亮。
咱们经常使用的垂直居中方式就是使用line-height
,可是这种方法在Android
设备下并不能彻底居中。
具体缘由是由于Android
中文字体排版的问题,能够参考 知乎:Android浏览器下line-height垂直居中为何会偏离?
经过设置字体,确实可以解决一部分偏离的问题。但仍然会出现一些略微偏离的状况,听说与行高奇数偶数有关。不过已经不太容易分辨了,若是仍是不能接受的话建议经过设置上下padding的方式进行垂直居中,再根据具体状况进行微调。
欢迎关注公众号 “大前端开发者”。给你带来更多的前端技术与资讯