前端适配方案

在进入正文之前,我们需要先了解一些viewport相关的概念。

viewport

一般来说,我们在代码的最开始会写上这么一句

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

移动端浏览器可以在一个比屏幕更宽的虚拟”窗口“中渲染页面,从而无需将所有页面都压缩进小屏幕里(那样会把很多没有针对移动端进行优化的站点打乱)。用户可以通过平移和缩放来浏览页面的不同区域。比如我们把一个页面的宽度写成了10000px,那么我们照样可以通过平移缩放来看到这个页面,当然这是不可取的,所以我们就需要以上代码,将viewport的width设置为设备的宽度,缩放的倍数是1,且不让用户进行缩放(这个可以根据实际业务场景来设置)。经过以上设置,我们就可以开始进入愉快写代码的第一步了~

  • 物理像素DP(device pixels)和css像素

物理像素一般在设备出厂的时候就被设置好了,也叫设备像素,单 位是pt(point)pt是一个物理单位,指的是组成显示器屏幕的绝对长度。我们买电视机的时候,会说,我买个70寸的电视机。

1英寸=72pt

px(pixel)是一个虚拟的单位,也是一个相对的单位。根据《CSS权威指南》的像素理论中的解释:

显示器上的小色框是像素
CSS2.1 建议采用96ppi(pixels per inch),这是Windows机器常用的度量。Mac系统下用的是72ppi。

摘录来自: Eric Meyer. “CSS权威指南第三版”。 iBooks.

1px=1/ppi英寸

通过inch就可以连接器pt和px的关系。


mac网页的例子
  • 设备独立像素DIP(Device independent Pixel)

设备独立像素,也称为逻辑像素,也叫css像素。我们可以通过screen.width或者screen.height输出。比如iPhone的css像素就是375px*667px,iPhone 6 则采用了750×1334分辨率的屏幕,PPI值为326。

iphone6示例图

物理像素和css像素的计算公式是:

DPR = 物理像素/CSS像素

css reset样式重置

为什么要进行css reset操作?

css reset主要是因为html标签在浏览器中都有各自的默认样式。

比如: p 标签有上下边距,strong标签有字体加粗样式,em标签有字体倾斜样式。不同浏览器的默认样式之间也会有差别,例如ul默认带有缩进的样式,在IE 下,它的缩进是通过margin实现的,而Firefox下,它的缩进是由padding实现的。在切换页面的时候,浏览器的默认样式往往会给我们带来麻烦,影响开发效率。所以解决的方法就是一开始就将浏览器的默认样式全部去掉,更准确说就是通过重新定义标签样式。

常用的适配方案

  • flex
<div class="content">
     <div class="con">
         <div class="a"></div>
     </div>
     <div class="con">
         <div class="a"></div>
     </div>
     <div class="con">
         <div class="a"></div>
     </div>
</div>

    .content{
         display: flex;
    }
    .con{
         display: flex;
         justify-content:center;
         align-items:center;
         flex:1;
         height: 300px;
         background: #999;
         color:#fff;
         border:1px solid #000;
    }
    .a{
         width: 30px;
         height: 30px;
         background: #f00;
    }
demo

demo地址

  • 媒体查询media query

    一个媒体查询由一个可选的媒体类型和零个或多个使用媒体功能的限制了样式表范围的表达式组成,例如宽度、高度和颜色。媒体查询,添加自CSS3,允许内容的呈现针对一个特定范围的输出设备而进行裁剪,而不必改变内容本身。

    我们把上面flex的css换掉其中a的样式,来看一下media query的作用。

    .a{
     background:#f00;
    }
    @media (max-width: 800px) {
     .a {
     width:50px;
     height:50px;
     font-size:12px;
     color:#2e9900;
     }
    }
    @media (min-width:801px) and (max-width:1000px) {
     .a {
     width:200px;
     height:200px;
     font-size:20px;
     color:blue;
     }
    }
    @media (min-width: 1001px) {
     .a {
     width:450px;
     height:450px;
     font-size:40px;
     }
    }

media query demo

  • transform-scale

其实我自己觉得transform-scale是一个不错的适配方式,简单明了,而且暂时也没有遇到过什么适配方面的大坑,相对而言还比较精确。

处理方式很简单,样式完全按照设计稿的px来写。然后在js中计算当前页面的宽度与设计稿的宽度的比,直接对body进行transform-scale的缩放。

如果非要说有什么问题的话,那就是如果需要考虑横屏受众,那就得针对一些横屏的状态做一些特殊处理。还有就是transform-scale缩小没有问题,放大的话,会导致页面模糊。

这个方案就看自己业务需求来选择了。

  • rem

rem算是一个使用很广泛的适配方案了。

实现的方式就是给html根节点设置一个font-size,作为页面计算的基准。一般这个基准会根据设计稿来定。

假设设计稿的宽度是750px,那最初我们可以将font-size设为75px,页面宽度就是10rem。

然后在页面中用js动态获取一下当前页面宽度,计算出页面宽度与750px的比例,获取当前页面根节点上应该带上多大的font-size,假设当前页面宽度是375px,那么根节点上带上的font-size应该是37.5px。

这个方案是一个与dpr无关的方案,就是说完全依赖的是设备独立像素而不是设备的物理像素,这样就会存在一个问题,在dpr较大的高清屏上,可能导致模糊。

当然,我们也是可以加上dpr来计算根节点的font-size的。

  • flexible.js

flexible是手淘的一套解决方案,这是一套dpr相关的解决方案。

实现的原理是:

flexible将页面分成100份,即100a,10a=1rem。比如,页面宽度为750px,那么一份为75px,1rem=75px。

通过js动态获取当前页面的dpr和设备独立像素。拿iPhone 8 plus举例,得到dpr是3,设备独立像素是414px。那么html上写的font-size的大小是这么计算的:

dpr * 414 / 10

最终得到的font-size值是124.2px,然后在meta的initial-scale里会根据dpr再进行一下页面缩放,这就可以保证页面的精细程度。

但是如果在meta viewport中手动设置了initial-scale,那么不管js获取到的dpr是多少,都会强制认为dpr是手动设置的值;

手淘处理文字的方式,并没有采用rem,因为rem计算出的小数,在对小数敏感度不一样的机型上会导致展示误差,且小于12px的文字并不会正常被渲染。也会导致一些line-height的问题。

  • vm

随着前端技术的演进,vw这个单位又走上了历史的舞台。

CSS Values and Units Module Level 3中和Viewport相关的单位有四个,分别为vwvhvminvmax

-   `vw`:是Viewport's width的简写,`1vw`等于`window.innerWidth`的`1%`

-   `vh`:和`vw`类似,是Viewport's height的简写,`1vh`等于`window.innerHeihgt`的`1%`

-   `vmin`:`vmin`的值是当前`vw`和`vh`中较小的值

-   `vmax`:`vmax`的值是当前`vw`和`vh`中较大的值

常见的屏幕适配问题和解决方案

  • line-height
    一般客户端的webview会有一个默认的line-height,大概会是在22px的样子。我们有可能会遇到一个问题就是,在我们设置好一个line-height之后,但是渲染出来的文字相对于我们预想的是偏上的。导致这个问题的原因是,我们设置的line-height是小于webview预设的最小line-height的,这样我们设置的那个值会被忽略。
    解决的方案是:
    尽量保证font-size是大于12px的,将line-height设置为1,使用上下padding使文字居中。在一些必须需要font-size小于12px的地方,可以先放font-size大于12px,再用transform:scale去缩小。
    但是这一点从实际经验来看,我更偏爱手淘的方案,根据dpr或者mediaquery设置一个固定的字体,这就需要和设计同学定下一个设计规范。
  • 中英文的字号一样,但是实际高度却不一样
    文字的大小,取决于设计文字的人,就像我们前几天遇到的英文比中文同字号小的问题,如果光靠上下的padding来写的话,那就可能会出现纯英文或者数字那块会比较矮。
  • 1像素问题
    产生原因:因为dpr高的设备下,写的1像素,实际是比1的dpr倍。
    解决方案:1)如果整体缩放页面的话,1像素的线也会被一起缩放
    2)可以将线条所在元素用transform-scale缩小
  • 如果设计师在设计稿上使用的文字很细,比如华文细黑这样的,那前端为了适配更完美,可以用一个样式-webkit-font-smoothing: antialiased;
  • 在移动端我们写了overflow:scroll;之后,滑动可能并不能像我们预料中的那么顺畅,可以使用样式-webkit-overflow-scrolling: touch;
  • 如果input或button的有怪异的默认样式,尝试appearance:none;(-webkit-appearance:none;)

参考文档:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339