热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

rem适配的浏览器_关于Html5移动端适配不同分辨率的布局总结

关于现在比较流行的一些框架比如bootstrap,用得多的人会发现bootstrap确实在做扁平化风格的网站方面,提供了很大的便利,适配不

c89948ffc5a3083af6f069b4ce66b75a.gif

关于现在比较流行的一些框架比如bootstrap,用得多的人会发现bootstrap确实在做扁平化风格的网站方面,提供了很大的便利,适配不同分辨率的pc端,包括能适配到移动端。

但是就我个人而言,从pc端适配到移动端这种一整套的方式还是有所不妥的,毕竟pc端显示的内容相对于移动端来说是很多很繁琐的,而移动端显示的风格大多以扁平化为主,屏幕显示的内容也不宜过多过于繁琐,所以要想直接从pc端适配到移动端的这一整套流程下来,只适用于一些内容不多的扁平化小网站。

好了进入主题,今天主要说说html是怎么适配不同分辨率的手机的,bootstrap虽然适配了整个屏幕的大小,但是你会发现,无论在哪个分辨率底下,字体的大小都是不会变的,没有做到不同的分线率显示不同的字体大小,这会造成一个问题,比如说在iPhone6的屏幕分辨率下,可以正常显示一段文字,但是在iphone5的屏幕分辨率比较小,那么那段文字显示就会出现异常,这种情况在开发的过程中经常会出现。

那么怎么让文字适配不同分辨率呢,不多说直接上代码:

adce7e925aa6fdbfb0b8b092a356dab6.png

以上是我自己总结的一段适配移动端的代码,安卓最大分辨率是750,那么我也以750为分界点,来设置项目的根字体大小。

那要怎么应用呢,主要是在单位的应用上,这里推荐使用rem,对rem不熟的朋友可以先去了解一下。

如下给一个布局的例子,比如在iphon6的分辨率为375,那么.p{font-size:1rem}

此时在iphone6屏幕上显示的字体大小就是1*20 = 20,也就是20px大小,而750的分辨率下的字体大小就是1*40 = 40,也就是40px大小,所以在布局的时候会涉及到px与rem两种单位间的换算问题。

这里推荐一个在线小工具http://alurk.com/,这个可以一次性将px全部转为换rem,http://pxtoem.com/这个可以一个一个的转换,看具体需求了。当然,还有其他方式的适配代码。

第二部分


rem 作为一个低调的长度单位,由于手机端网页的兴起,在屏幕适配中得到重用。使用 rem 前端开发者可以很方便的在各种屏幕尺寸下,通过等比缩放的方式达到设计图要求的效果。

rem 的官方定义『The font size of the root element.』,即以根节点的字体大小作为基准值进行长度计算。一般认为网页中的根节点是 html 元素,所以采用的方式也是通过设置 html 元素的 font-size 来做屏幕适配,但实际情况真有这么简单吗?

首先我们来看看使用 rem 实现手机屏幕适配的常用方案。

以设计稿的宽度为640px,即:designWidth = 640,同时设定在640px屏宽下 1rem=100px ,即:rem2px = 100。

设置 1rem=100px 的优点不言而喻。前端开发者在切图、重构页面的时候,通过直接位移小数点的方式,就可以将UI图中测量到的 px 值换算成对应的 rem 值,方便快捷。

此外,在 head 中我们还设置了:

viewport 的作用很重要,但不是本文的重点所以不展开,有兴趣的同学可以自行搜索。

先来看看具体方案:

下面四个方案来自同事共享,原理都是采用等比缩放的方式 —— 获得目标屏幕宽度和设计稿宽度的比,作为 rem 的基值(缩放系数),设置为html标签的字体大小。不同的只是在于性能取舍和书写习惯。

方案1

@media screen and (min-width: 320px) {html{font-size:50px;}}

@media screen and (min-width: 360px) {html{font-size:56.25px;}}

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

@media screen and (min-width: 400px) {html{font-size:62.5px;}}

@media screen and (min-width: 414px) {html{font-size:64.6875px;}}

@media screen and (min-width: 440px) {html{font-size:68.75px;}}

@media screen and (min-width: 480px) {html{font-size:75px;}}

@media screen and (min-width: 520px) {html{font-size:81.25px;}}

@media screen and (min-width: 560px) {html{font-size:87.5px;}}

@media screen and (min-width: 600px) {html{font-size:93.75px;}}

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

@media screen and (min-width: 680px) {html{font-size:106.25px;}}

@media screen and (min-width: 720px) {html{font-size:112.5px;}}

@media screen and (min-width: 760px) {html{font-size:118.75px;}}

@media screen and (min-width: 800px) {html{font-size:125px;}}

@media screen and (min-width: 960px) {html{font-size:150px;}}

方案2

@media screen and (min-width: 320px) {html{font-size:312.5%;}}

@media screen and (min-width: 360px) {html{font-size:351.5625%;}}

@media screen and (min-width: 375px) {html{font-size:366.211%;}}

@media screen and (min-width: 400px) {html{font-size:390.625%;}}

@media screen and (min-width: 414px) {html{font-size:404.2969%;}}

@media screen and (min-width: 440px) {html{font-size:429.6875%;}}

@media screen and (min-width: 480px) {html{font-size:468.75%;}}

@media screen and (min-width: 520px) {html{font-size:507.8125%;}}

@media screen and (min-width: 560px) {html{font-size:546.875%;}}

@media screen and (min-width: 600px) {html{font-size:585.9375%;}}

@media screen and (min-width: 640px) {html{font-size:625%;}}

@media screen and (min-width: 680px) {html{font-size:664.0625%;}}

@media screen and (min-width: 720px) {html{font-size:703.125%;}}

@media screen and (min-width: 760px) {html{font-size:742.1875%;}}

@media screen and (min-width: 800px) {html{font-size:781.25%;}}

@media screen and (min-width: 960px) {html{font-size:937.5%;}}

方案3

var designWidth = 640, rem2px = 100;

document.documentElement.style.fontSize =

  ((window.innerWidth / designWidth) * rem2px) + 'px';

方案4

var designWidth = 640, rem2px = 100;

document.documentElement.style.fontSize =

  ((((window.innerWidth / designWidth) * rem2px) / 16) * 100) + '%';

为了更避免理解上的混乱,我在上面js的代码中加了 ( ) ,实际代码中是不需要的。

详细分析一下,rem 和 px 直接的转换公式可以写为:

1rem = 1 * htmlFontSize

htmlFontSize 为 html 元素的字体大小。

首先来看方案1中,在屏宽为640px情况下的设置:

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

可以很明显的表现出这一点 1rem = 1 * 100px ,同我们最初的设定。那么我们要得到其它屏幕大小的 htmlFontSize 值要怎么办。很简单如方案3,因为我们的采用等比缩放的方式适配,所以计算目标屏幕宽度和设计稿的宽度的比即可:

window.innerWidth / designWidth * rem2px + 'px'

由于浏览器默认字体大小为 16px,所以当我们使用百分比作为根节点 html 的字体大小时,即html元素的font-size值设置为一个百分比值,rem 的计算方式就会改为:

defaultFontSize = 16px
1rem = 1 * htmlFontSize * defaultFontSize

如方案2中,在屏宽为640px情况下的设置:

@media screen and (min-width: 640px) {html{font-size:625%;}}

应用上面的公式:

同样的可以得到所有屏幕大小下,html 的 font-size 值的计算公式,即为方案4:

1rem = 1 * 625% * 16px

其中:625% * 16 = 6.25 * 16 = 100

所以:1rem = 1 * 100px

通过方案3和方案4的公式,就可以很方便的生成方案1和方案2中的css。

如下面两张图,是在屏宽为360px下的效果,通过计算目标为:1rem = 56.25px。方案3设置值为:56.25px,方案4设置值为:351.5625%

956049aa4f41521fac1a0c53244097db.png

到目前为止貌似很完美的解决了问题,实际情况当然是出现了意外。在有些 Android 手机上,浏览器或 webview 的默认字体是随着系统设置的字体改变的。这样就会导致默认字体大于或小于 16px。

修改默认字体大小后,我们再看方案3和方案4。

同样在屏宽为360px下,我们调大系统字体大小,如下面的效果

设置前 html 元素的字体大小的计算值为 18px ,设置后的计算值为 65px ,由于屏幕宽度没有改变,我们的目标值,即我们在 html 元素上设置的 font-size 值也没有变化任然为 56.25px,而最终计算值出现了偏差。

210a6d7d66f1333f5e72b40527a0301f.png

分析偏差前,先来看在360px屏宽下,方案3和方案4的计算过程:

方案3:

document.documentElement.style.fontSize = 56.25px

htmlFontSize = 56.25px

1rem = 1 * htmlFontSize = 56.25px

实际为:

1rem = 64.6875px

方案4:

document.documentElement.style.fontSize = 351.5625%

htmlFontSize = 351.5625%

defaultFontSize = 18px

1rem = 1 * htmlFontSize * defaultFontSize = 351.5625% * 18px = 63.28125px

351.5625% * 18 = 63.28125

实际为:

1rem = 64.6875px

貌似方案4的计算结果很接近实际效果,而方案3偏差很大。再来比较方案3和方案4的计算公式:

// 方案3

document.documentElement.style.fontSize =

  window.innerWidth / designWidth * rem2px + 'px';

// 方案4

document.documentElement.style.fontSize =

  window.innerWidth / designWidth * rem2px / 16 * 100 + '%';

方案4较于方案3其实多除了一个16,可以推测浏览器在计算 rem 的具体值时,如果 html 设置的 font-size 为 px 值时会先除以 16 ,然后再乘以 htmlFontSize。

1rem = 1 * (56.25px / 16) * 18

1 * (56.25 / 16) * 18 = 63.28125

方案4存在问题,是因为系统的默认字体改为了 18px ,但是我们在计算百分比是时候,还是以 16px 为基准值进行计算,所以出现偏差(计算值和实际值之间还有一点偏差这个在后面会提到)。

而在方案3中,我们其实是不考虑浏览器默认字体大小的,但在实际使用的过程中,浏览器还是除了 16 ,而此时默认字体大小为 18px。得出如下在 html 的 fontSize 设置为 px 的情况下 rem 的计算公式为:

1rem = 1 * (htmlFontSize / 16) * defaultFontSize

在系统设置的字体大小发生改变时,defaultFontSize 会跟着改变,而 16 不会变化。所以方案3虽然表面上不考虑默认字体大小的变化,只关注屏幕与设计稿之间的宽度比,但在实际计算中还是使用到了默认字体大小,而且还有一个不变的 16 在作祟,导致方案3失败。

所谓的「root element」其实不是想象的那样,一个是16,一个是18,到底取的是那个 root element 的字体大小。

ok,rem 的计算的时候,px 的方式会有一个16不随系统字体大小改变,所以我们采用百分比的方案,绕开这个问题。

采用百分比的方案4因为在计算时写死了默认字体大小 16px。所以它的偏差在于没能动态的获取默认字体大小。更新如下:

方案4.1

var designWidth = 640, rem2px = 100;

var h = document.getElementsByTagName('html')[0];

var htmlFontSize = parseFloat(window.getComputedStyle(h, null)

                                    .getPropertyValue('font-size'));

document.documentElement.style.fontSize =

  window.innerWidth / designWidth * rem2px / htmlFontSize * 100 + '%';

效果如下图:

16px 的图中,设置后的 html 的 font-size 与 1rem 的实际值有偏差,同时 6.4rem 的计算值也有偏差。通过查看代码发现html的font-size使用的是: getPropertyValue('font-size') 而 1rem 使用的是getPropertyValue('width'),偏差出在计算 font-size 的时候浏览器进行了四舍五入。rem 定义中的另一个元素「font size」也不能按字面意思使用,宣告失守。

18px 中的偏差,以及上文中方案4在 18px 实际值和计算值出现的偏差都是同样的问题。所以基准值还需要修改。

f2b3b5a7d5a0aeaa73f1c2ce65944975.png

在更新一版,方案4.2:

02df1d61d0e1765f5d614d964ed89a72.png

效果如下图:

6756e4d6faf6763de2f6c21b833fdd59.png

到此为止,rem 在默认字体不是 16px 的情况下的处理已经解决,考虑到还有设计屏幕旋转,最终手机端的解决方案为:

b2febdaebc3431db8f4977af9687c88a.png

回过头来再看 rem 的定义,『The font size of the root element.』。我们以为的 root element —— html 其实还有个影子在作祟,而我们以为的 font-size 其实是个近似值。

*声明:内容与图片均来源于网络(部分内容有修改),版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。

20b0057261d68238655e98fa485c1c1a.pnge4e79e36d1c4970486a79bd8b570cd3d.png公众号ID:tanzhouweb扫码关注最新动态你今天好看吗?



推荐阅读
  • 从零基础到精通的前台学习路线
    随着互联网的发展,前台开发工程师成为市场上非常抢手的人才。本文介绍了从零基础到精通前台开发的学习路线,包括学习HTML、CSS、JavaScript等基础知识和常用工具的使用。通过循序渐进的学习,可以掌握前台开发的基本技能,并有能力找到一份月薪8000以上的工作。 ... [详细]
  • 如何在HTML中获取鼠标的当前位置
    本文介绍了在HTML中获取鼠标当前位置的三种方法,分别是相对于屏幕的位置、相对于窗口的位置以及考虑了页面滚动因素的位置。通过这些方法可以准确获取鼠标的坐标信息。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • 本文介绍了响应式页面的概念和实现方式,包括针对不同终端制作特定页面和制作一个页面适应不同终端的显示。分析了两种实现方式的优缺点,提出了选择方案的建议。同时,对于响应式页面的需求和背景进行了讨论,解释了为什么需要响应式页面。 ... [详细]
  • 单页面应用 VS 多页面应用的区别和适用场景
    本文主要介绍了单页面应用(SPA)和多页面应用(MPA)的区别和适用场景。单页面应用只有一个主页面,所有内容都包含在主页面中,页面切换快但需要做相关的调优;多页面应用有多个独立的页面,每个页面都要加载相关资源,页面切换慢但适用于对SEO要求较高的应用。文章还提到了两者在资源加载、过渡动画、路由模式和数据传递方面的差异。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文总结了在编写JS代码时,不同浏览器间的兼容性差异,并提供了相应的解决方法。其中包括阻止默认事件的代码示例和猎取兄弟节点的函数。这些方法可以帮助开发者在不同浏览器上实现一致的功能。 ... [详细]
author-avatar
手机用户2502891985
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有