-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
移动端H5解惑-页面适配(二) #28
Comments
“我们可以动态调整100个因子,调整的2个约定条件是: html根字体大小位于:10px ~ 100px 之间 这个是没必要的吧,可以再body元素上再设置font-size成合适的字体尺寸,比如28rem/$cssRadio。 |
@tiemei 感谢关注。首先我文章中的原话不通,已经修改。 |
厉害!!!!!谢谢分享 |
mark |
请问你的rem完美方式有没有在移动端遇到过奇怪的问题,想尝试一下 |
@FirstAurora183 这个方案现在比较通用,可以尝试。现在唯一遇到的问题,就是:用户自己设置了手机字体,比如:自定义手机主题,放大了手机字体大小,这种情况会影响到REM的排版。这个问题其实也可以解决,只是我们这边讨论过,觉得这毕竟是小众群体,就没管。如果你们以后遇到这个情况,也有解决办法,可以再讨论。其它的暂时没遇到什么问题。 |
请问动态因子的作用到底是啥?在设置html font-size的时候乘以了因子,在使用rem的时候又除了。这不是跟没有动态因子一样吗? |
@MachLau 主要原因是:在PC上浏览器最小fontSize=12,在手机上最小fontSize=8,当字体小于最小字体时,统统按最小字体计算。比如在手机上:html fontSize=8px,元素width=0.1rem,实际渲染到页面上的元素尺寸是width=0.8px;而html fontSize=0.1px,元素width=8rem,实际渲染到页面上的尺寸是width=64px。原因就是0.1px小于最小值8,按照8计算。 这篇文章我会重新再整理一下发布,到时候会仔细讲这一块,感谢关注,点赞。 |
明白了,非常感谢! |
有个问题想请教一下,移动端页面设计稿是以宽度为375px为基准进行设计的,图片切图分为iOS和Android,我们在编写页面的时候,需要用到一些图片作为背景或者用于装饰,应当使用iOS的@2x尺寸的图片还是Android的xhdpi尺寸的图片? |
多谢,我们现在比较坑爹的一点就是设计图都是以iOS版本标注为准,但是一些图标的切图则是分为iOS和Android两种,所以让我这个写HTML页面的小开发仔很头大…… |
@zhoubhin 想开点老弟,😁 |
时常告诫一下自己:做人要淡定~ |
这里的scss如果用css要怎么写? |
@Zuson 这个可能有点难办了,因为纯css不能定义方法,基本没法实现。要么使用scss/less这种css开发语言,要么使用js去处理。 |
一、基础概念
在了解如何做H5页面适配前,大家都应该把移动端涉及的一些概念搞明白,比如:
dpr
是什么意思?移动端H5解惑-概念术语(一)
二、为什么要做页面适配
2.1 PC端为什么要解决浏览器兼容
因为在PC端,由于浏览器种类太多啦,比如几个常用的:IE、火狐、Chrome、Safari等。同时,由于历史原因,不同浏览器在不同时期针对当时的WEB标准有一些不一样的处理(虽然大部分一样),比如:IE6、IE8、IE10+等对于一些JS事件处理、CSS样式渲染有所不同。
而恰恰又有一些人在使用着不同类型的浏览器,以及不同浏览器的不同版本。所以,为了能让你的网站让这些不同的人看到效果一致,你就不得不做兼容,除非这些人不是你的目标用户。
2.2 移动端为什么要做适配
在移动端虽然整体来说大部分浏览器内核都是webkit,而且大部分都支持CSS3的所有语法。但是,由于手机屏幕尺寸不一样,分辨率不一样,或者你需要考虑横竖屏的问题,这时候你也就不得不解决在不同手机上,不同情况下的展示效果了。
另外一点,UI一般输出的视觉稿只有一份,比如淘宝就会输出:
750px
宽度的(高度是动态的一般不考虑)(详情),这时候开发人员就不得不针对这一份设计稿,让其在不同屏幕宽度下显示一致
。一致
是什么意思?就是下面提到的几个主要解决的问题。三、页面适配主要解决的问题
3.1 元素自适应问题
举个栗子:
在
1080px
的视觉稿中,左上角有个logo,宽度是180px
(高度问题同理可得)。那么logo在不同的手机屏幕上等比例显示应该多大尺寸呢?
其实按照比例换算,我们大致可以得到如下的结果:
375px
的手机上,应该显示多大呢?结果是:375px * 180 / 1080 = 62.5px
360px
的手机上,应该显示多大呢?结果是:360px * 180 / 1080 = 60px
320px
的手机上,应该显示多大呢?结果是:320px * 180 / 1080 = 53.3333px
以下就是一些实现思路:
方案1:使用css的媒体查询
@media
这个方案有2个比较突出的问题:
@media
查询块;@media
中定义一遍不同的尺寸,这个代价有点高。方案2:使用
rem
单位注意我们的推导公式:
375px
的手机上,应该显示多大呢?结果是:375px * 180 / 1080 = 62.5px
360px
的手机上,应该显示多大呢?结果是:360px * 180 / 1080 = 60px
320px
的手机上,应该显示多大呢?结果是:320px * 180 / 1080 = 53.3333px
方案2有效的解决了方案1中,同一个元素需要在多个 media 中写的问题,这里只需要多定义几个 media 就可以大致解决问题了。
但是本方案仍然有以下问题:
@media
查询语句,多一种机型就需要多写一套查询语句,而且随着现在手机的层出不穷,这个页面很有可能在一些新出的机型上有问题。针对除以1080我们能不能直接放到html的font-size上,变成这样:
如果变成这样,那么
.logo
的css中就只需要按设计稿的尺寸大小写就可以了。到底可不可以呢?答案是:不可以。
主要原因是,浏览器有最小字体限制:
font-size=12
font-size=8
如果小于最小字体,那么字体默认就是最小字体。
再来看上面的css,比如:
所以当你这么设置font-size时,在手机上由于小于最小字体8px,所以页面会按照默认字体算。
所以,最终就相当于你是这么设置的:
所以,大家在设置html的font-size的时候一定要保证最小等于8px!
因而为了解决这个问题,建议大家使用Sass这种Css开发语言,可以定义公式的,这样写css就方便了。
最终使用Sass的代码如下:
以上方案虽然解决了问题,但任然有以下缺陷:
@media
calc()
,这个也挺麻烦的。方案3:js动态设置根字体
由于方案2最主要的问题就是需要针对不同的屏幕尺寸,定义多个
@media
,所以我们先将这个字体设置改为动态设置。注意我们的推导公式:
375px
的手机上,应该显示多大呢?结果是:375px * 180 / 1080 = 62.5px
360px
的手机上,应该显示多大呢?结果是:360px * 180 / 1080 = 60px
320px
的手机上,应该显示多大呢?结果是:320px * 180 / 1080 = 53.3333px
需要注意:
然后Sass中就可以按照设计稿的尺寸大小去写就行了:
如果不考虑别的因素,只是页面元素大体适配的话,该方案基本就满足要求了,但是现实中我们其实还有很多问题,所以我们的方案还需要继续优化。
3.2 文字rem问题
文字也采用rem的单位主要有什么问题呢?
23.335px
这样的奇葩的字体大小,可能还会因此出现锯齿、模糊不清等问题;3.5 横竖屏显示问题
会仔细讲)。对于以上问题,我个人的建议:
如果一定要解决这个问题,那么字体就不要使用rem方案了,而是继续使用px单位。
我们上面提到
大屏
小屏
其实隐含的意思并不是手机屏幕大,而是手机的屏幕分辨率不一样,其实就是dpr不一样,所以我们针对不同的dpr设置具体的字体就可以了。比如,我们针对页面的标题的字体大小就可以如下设置:
3.3 高清图问题
先来看看 这里 这篇文章,有讲解了为什么在有些屏幕上要使用
@2x
@3x
的高清图。再来看看 这里 讲解了具体的高清图的解决方案。
我这里简单归纳下。
3.3.1 对于
<img>
标签引入的图片高清解决方案1、使用
srcset
标签2、使用js自带的
Image
异步加载图片3.3.2 对于背景图片高清解决方案
1、使用
media query
来处理2、使用
image-set
来处理(有兼容问题)3.4 1像素问题
什么是 1像素问题 ?
关于
dpr
,不理解的,可以看看之前的 这篇 文章。问题描述清楚了,我们该怎么处理呢?
方案1:使用css3的
scaleY(0.5)
来解决比如:div的border-top的1px问题解决。
但是,这种方案只能解决直线的问题,涉及到圆角之类的,就无能为力!
方案2:页面缩放解决问题
我们先来讲讲页面缩放能解决1px问题的原理示。
首先大家需要了解一些
viewport
的常识,参考:这里假如以下手机的
dpr=2
对于dpr=2的手机设备,1px就会有
2x2
的物理像素来渲染,但是当缩放以后其实就变成1x1
个单位渲染了,看下面示意图:所以,我们的思路就是将真个页面缩小dpr倍,再将页面的根字体放大dpr倍。这样页面虽然变小了,但是由于页面整体采用rem单位,当根字体放大dpr倍以后,整体都放大了,看上去整体样式没什么变化。
1、将scale设置为1/dpr
假如:dpr = 2
2、clientWidth获取的值会自动扩大dpr倍
比如,以前是360px,当页面缩小0.5倍,获取到的值会变为720px。
不知道这个原理的,这篇文章讲的还是比较清楚:这里
3、css中涉及到1像素问题的地方使用
px
作为单位比如:
以上步骤最终整理的结果:
html:
js:
scss:
3.5 横竖屏显示问题
横竖屏问题,就是当你横屏手机、竖屏手机时看到的不一样的效果问题。
我这里要说的这个问题,就是设计师会针对横屏或者竖屏,做不一样的设计,比如:横屏时显示摘要,竖屏时只有标题,这种情况下,我们应该怎么适配的问题。
关于横竖屏问题,我将会分2个部分来说明:
3.5.1 横竖屏显示内容问题
我们知道横屏,相当于屏幕变宽了,这时候一行显示的内容就可以更多。所以,设计师可能会对横竖屏做2种不同的内容设计,如:
如果设计师本身就设计了2套样式,那么我们只需要准备2套css,依据横竖屏直接显示对应的样式,然后html中做好兼容即可。
下文会将如何判断横竖屏。
3.5.2 横竖屏显示样式问题
这里有个要说的就是,设计师没有设计横屏的样式,那么如果我们按照上文提到的方案去处理,那么就会发现在横屏模式下字体显得非常大(因为屏幕宽了),显示的内容就少了。
这种情况会显得很不协调,虽然还是等比例显示的,只不过需要多拖动下滚动条而已,但是你会觉得很怪。尤其是再有弹出框的时候,会更麻烦,弹出框有时候可能还会显示不完全。。。
比如,下面的样式:
像这种问题,我们上面提到的依据屏幕宽度自动调整根目录font-size的大小,就有点不合适了。这样虽然保证了横向的比例是严格按照设计搞来的,但是显示上非常丑。
所以,我们一般的做法就是在横屏的时候将
deviceWidth=deviceHeight
。以上3组画面对比我们得到的效果是:
所以,经过我们的实际对比体验以后,一致认为横屏时让
width=height
体验比较好。附上核心代码:
3.5.3 附1:JS检测横竖屏
js获取屏幕旋转方向:
window.orientation
3.5.4 附2:CSS判断横竖屏
3.6 手机字体缩放问题
手机字体缩放是什么问题呢?
就是当你在手机
设置 -> 字体设置
中将字体放大或者缩小,使得手机整体系统字体发生了变化,这时候可能就会影响到H5页面正常的显示。经过实际测试,这个问题当前发生的概率不是很大,因为很多手机厂商都已经做了保护措施。但是为了保险起见,我们还是有必要进行检测,一旦不一样就要采取措施。
3.6.1 如何检测手机字体不是默认字体
3.6.2 如果手机字体不是默认字体如何处理
比如:你想设置的字体大小为100px,但是实际大小却为50px,那么你可以确定其实用户字体是缩放了0.5,这时候你就需要将你的字体扩大1倍,这样才能保证实际页面的字体是100。
所以,按照这个等比例换算以后,我们就需要重新设置页页面的font-size。
这么做理论上已经解决了问题,但是还有点瑕疵,问题就是:
如何解决这个问题?思路就是:
最终代码片段如下:
四、最终适配方案(v1.0)
除了上面一步步的分析中间的原理之外,我们可能还需要考虑或者遇到以下问题:
document.documentElement.clientWidth=0
的bug?所以,在尽可能的解决诸多问题后,最终的脚本如下:
html:
js:
scss:
五、新页面适配技术可以考虑(v2.0)
如果不太考虑老的手机型号,可以采用
viewport
单位。由于我本人也没有在项目中使用这个方案,所以不过多发表言论,大家有兴趣的可以研究下。
具体方案细节参考:
六、后记
讲了这么多,这里总结下,任何事情弄懂原理最重要!
比如,当你首次看 使用Flexible实现手淘H5页面的终端适配 这篇文章的时候你会很感慨,感觉很有收获,但是当你实际开始项目的时候,却不知道该怎么下手。
俗话说,台上一分钟,台下十年功。
为了写本文以及姊妹篇,我个人零零散散的时间加起来不下1个月,一直到(
2016年12月2日
)才发表了本文的第一版。由于收到一些流言反馈和后续知识的积累,于是决定今天(2018年08月01日
)再把它重新整理一遍,以让大家更清楚这中间的原理。因为中间涉及的东西太多,只要有一个知识有些不清楚,可能就会卡克!比如这个概念
dips
,不同的文章有不同的说法,而且还给你解释了它跟dip
的不同,其实就是指CSS像素
,这些人故意发明一些专业词汇,搞的你晕头转向,所以,当你看了我的这两篇文章,也许还是一知半解,这很正常,慢慢来,多多练习,相信你会明白的。如果还有哪里不清楚,或者本文有错误的地方,感谢批评指正。
参考
(全文完)
The text was updated successfully, but these errors were encountered: