面试官:你了解过移动端适配吗?

一、为何要移动端适配?

通常状况下设计稿的设计师按照375的尺寸设计,然而,在如今移动终端(就是手机)快速更新的时代,每一个品牌的手机都有着不一样的物理分辨率,这样就会致使,每台设备的逻辑分辨率也不尽相同,此时357的设计稿,若是想要还原那基本是不可能了,由于若是一个左右布局,左边若是写死,右边自适应的话,每一个设备的右边所展现的内容大小就不尽相同,这是移动端适配就显得尤为重要

既然要了解前世此生,咱们就从几个概念提及先上一张图css

下面咱们一个个解析html

屏幕尺寸

屏幕尺寸是以屏幕对角线的长度来计量,计量单位为英寸。

如图所示两个对角线的长度就是这个屏幕的尺寸前端

像素

咱们看到上图320x480叫分辨率,而这个所谓的分辨率就是说白了就横向320个像素纵向480个像素组成webpack

什么叫像素呢?

像素(Pel,pixel;pictureelement),为组成一幅图像的所有亮度和色度的最小图像单元。电视的图像是由按必定间隔排列的亮度不一样的像点构成的,造成像点的单位也就是像素,组成图像的最小单位就是像素。从计算机技术的角度来解释,像素是硬件和软件所能控制的最小单位。它指显示屏的画面上表示出来的最小单位,不是图画上的最小单位。一幅图像一般包含成千上万个像素,每一个像素都有本身的颜色信息,它们紧密地组合在一块儿。因为人眼的错觉,这些组合在一块儿的像素被当成一幅完整的图像。当修改图像的某区域,其实是在修改该区域内的像素。对这些像素修改的好与坏将决定最终图片的质量。单位面积内的像素越多,图像的效果就越好。彩色电视图像是由成千个像素点所组成的,并且每一个像素都是由红绿蓝三种颜色并排组成的。(注意每一个像素的大小是不固定的,他是根据设备的分辨率决定的,知识点,后面要考)

什么叫分辨率呢?

屏幕分辨率是指纵横向上的像素点数,单位是px。屏幕分辨率肯定计算机屏幕上显示多少信息的设置,以水平和垂直像素来衡量。就相同大小的屏幕而言,当屏幕分辨率低时(例如 640 x 480),在屏幕上显示的像素少,单个像素尺寸比较大。屏幕分辨率高时(例如 1600 x 1200),在屏幕上显示的像素多,单个像素尺寸比较小。

知道什么叫作分辨率后,有人就会奇怪,我记得苹果的苹果官网上的苹果6的分辨率为750x1334啊,可是设计稿上苹果6的分辨率为375x667啊,并且各个设备的分辨率都比实际分辨率小不少,这就牵扯到一些历史缘由了web

设备物理分辨率(设备像素)

相信咱们全部前端开发者,都是见证了手机这个移动设备发展的过程。从蓝屏手机,到彩屏手机,到诺基亚研发出来触屏手机,再到智能手机一步步发展下来,咱们的咱们的手愈来愈清晰,愈来愈大,因此咱们的屏幕发展也愈来愈迅速。数组

上图能够清楚的看到,不一样分辨率所带来的的差距浏览器

从最初的颗粒感至关大的屏幕,到720p再到1080p,甚至于如今各家旗舰手机的2k屏幕,咱们的物理分辨率在变得原来越大。这样就暴露出来一个问题,咱们若是手机分辨率翻倍,咱们的图像不就要被缩小一倍,咱们难道要在每一个设备上就出个设计稿,每一个设备的分辨不尽相同啊,其实你担心的问题,咱们的乔帮主在不少年前就想到了。这就是咱们的逻辑分辨率布局

逻辑分辨率(设备独立像素)

以下图所示,虽然设备物理分辨不一样,可是他的这个逻辑分辨率却都差很少,这就要感谢乔帮主了post

乔布斯在iPhone4的发布会上首次提出了Retina Display(视网膜屏幕)的概念,在iPhone4使用的视网膜屏幕中,把2x2个像素当1个像素使用,这样让屏幕看起来更精致,可是元素的大小却不会改变。今后之后高分辨率的设备,多了一个逻辑像素。这些设备逻辑像素的差异虽然不会跨度很大,可是仍然有点差异,因而便诞生了移动端页面须要适配这个问题,既然逻辑像素由物理像素得来,那他们就会有一个像素比值学习

设备像素比

设备像素比device pixel ratio简称dpr,即物理像素和设备独立像素的比值。为何要知道设备像素比呢?由于这个像素比会产生一个很是经典的问题,1像素边框的问题。

1px边框问题

当咱们css里写的1px的时候,因为它是逻辑像素,致使咱们的逻辑像素根据这个设备像素比(dpr)去映射到设备上就为2px,或者3px,因为每一个设备的屏幕尺寸不同,就致使每一个物理像素渲染出来的大小也不一样(记得上面的知识点吗,设备的像素大小是不固定的),这样若是在尺寸比较大的设备上,1px渲染出来的样子至关的粗矿,这就是经典的一像素边框问题

如何解决

核心思路,就是 在web中,浏览器为咱们提供了window.devicePixelRatio来帮助咱们获取dpr。在css中,可使用媒体查询min-device-pixel-ratio,区分dpr: 咱们根据这个像素比,来算出他对应应该有的大小,可是暴露个很是大的兼容问题

其中Chrome把0.5px四舍五入变成了1px,而firefox/safari可以画出半个像素的边,而且Chrome会把小于0.5px的当成0,而Firefox会把不小于0.55px当成1px,Safari是把不小于0.75px当成1px,进一步在手机上观察iOS的Chrome会画出0.5px的边,而安卓(5.0)原生浏览器是不行的。因此直接设置0.5px不一样浏览器的差别比较大,而且咱们看到不一样系统的不一样浏览器对小数点的px有不一样的处理。因此若是咱们把单位设置成小数的px包括宽高等,其实不太可靠,由于不一样浏览器表现不同。

至于其余解决一像素边框问题网上有一堆答案,在这里我推荐一种很是好用,而且没有反作用的解决方案

transform: scale(0.5) 方案

div {
    height:1px;
    background:#000;
    -webkit-transform: scaleY(0.5);
    -webkit-transform-origin:0 0;
    overflow: hidden;
}
复制代码

css根据设备像素比媒体查询后的解决方案

/* 2倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 2.0) {
    .border-bottom::after {
        -webkit-transform: scaleY(0.5);
        transform: scaleY(0.5);
    }
}

/* 3倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 3.0) {
    .border-bottom::after {
        -webkit-transform: scaleY(0.33);
        transform: scaleY(0.33);
    }
}
复制代码

如此,完美的解决一像素看着粗的问题

如何适配

viewport

视口(viewport)表明当前可见的计算机图形区域。在Web浏览器术语中,一般与浏览器窗口相同,但不包括浏览器的UI, 菜单栏等——即指你正在浏览的文档的那一部分。

那么在移动端如何配置视口呢? 简单的一个meta标签便可!

<meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; minimum-scale=1; user-scalable=no;">
复制代码

他们分别什么含义呢?

咱们在移动端视口要想视觉效果和体验好,那么咱们的视口宽度必去无限接近理想视口

理想视口:通常来说,这个视口其实不是真是存在的,它对设备来讲是一个最理想布局视口尺寸,在用户不进行手动缩放的状况下,能够将页面理想地展现。那么所谓的理想宽度就是浏览器(屏幕)的宽度了。

因而上述的meta设置,就是咱们的理想设置,他规定了咱们的视口宽度为屏幕宽度,初始缩放比例为1,就是初始时候咱们的视觉视口就是理想视口!

其中user-scalable设置为no 能够解决移动端点击事件延迟问题(拓展)

解决适配方法

一、rem适配

rem是CSS3新增的一个相对单位,这个单位引发了普遍关注。这个单位与em有什么区别呢?区别在于使用rem为元素设定字体大小时,仍然是相对大小,但相对的只是HTML根元素。这个单位可谓集相对大小和绝对大小的优势于一身,经过它既能够作到只修改根元素就成比例地调整全部字体大小,又能够避免字体大小逐层复合的连锁反应。目前,除了IE8及更早版本外,全部浏览器均已支持rem。对于不支持它的浏览器,应对方法也很简单,就是多写一个绝对单位的声明。这些浏览器会忽略用rem设定的字体大小

举个例子:

//假设我给根元素的大小设置为14px
html{
    font-size:14px
}
//那么我底下的p标签若是想要也是14像素
p{
    font-size:1rem
}
//如此便可
复制代码

rem的布局 不得不提flexible,flexible方案是阿里早期开源的一个移动端适配解决方案,引用flexible后,咱们在页面上统一使用rem来布局。

他的原理很是简单

// set 1rem = viewWidth / 10
function setRemUnit () {
    var rem = docEl.clientWidth / 10
    docEl.style.fontSize = rem + 'px'
}
setRemUnit();
复制代码

rem 是相对于html节点的font-size来作计算的。因此在页面初始话的时候给根元素设置一个font-size,接下来的元素就根据rem来布局,这样就能够保证在页面大小变化时,布局能够自适应,

如此咱们只须要给设计稿的px转换成对应的rem单位便可

固然,这个方案只是个过渡方案,为何说是过渡方案

由于当年viewport在低版本安卓设备上还有兼容问题,而vw,vh还没能实现全部浏览器兼容,因此flexible方案用rem来模拟vmin来实如今不一样设备等比缩放的“通用”方案,之因此说是通用方案,是由于他这个方案是根据设备大小去判断页面的展现空间大小即屏幕大小,而后根据屏幕大小去百分百还原设计稿,从而让人看到的效果(展现范围)是同样的,这样一来,苹果5 和苹果6p屏幕若是你按照设计稿还原的话,字体大小实际上不同,而人们在同样的距离上但愿看到的大小实际上是同样的,本质上,用户使用更大的屏幕,是想看到更多的内容,而不是更大的字

so,这个用缩放来解决问题的方案是个过渡方案,注定时代所淘汰

二、vw,vh布局

vh、vw方案即将视觉视口宽度 window.innerWidth和视觉视口高度 window.innerHeight 等分为 100 份。

vh和vw方案和rem相似也是至关麻烦须要作单位转化,并且px转换成vw不必定能彻底整除,所以有必定的像素差。

不过在工程化的今天,webpack解析css 的时候用postcss-loader 有个postcss-px-to-viewport能自动实现px到vw的转化

{
    loader: 'postcss-loader',
    options: {
        plugins: ()=>[
            require('autoprefixer')({
                browsers: ['last 5 versions']
            }),
            require('postcss-px-to-viewport')({
                viewportWidth: 375, //视口宽度(数字)
                viewportHeight: 1334, //视口高度(数字)
                unitPrecision: 3, //设置的保留小数位数(数字)
                viewportUnit: 'vw', //设置要转换的单位(字符串)
                selectorBlackList: ['.ignore', '.hairlines'], //不须要进行转换的类名(数组)
                minPixelValue: 1, //设置要替换的最小像素值(数字)
                mediaQuery: false //容许在媒体查询中转换px(true/false)
            })
        ]
}

复制代码

三、px为主,vx和vxxx(vw/vh/vmax/vmin)为辅,搭配一些flex(推荐)

之因此推荐使用此种方案,是因为咱们要去考虑用户的需求,用户之因此去买大屏手机,不是为了看到更大的字,而是为了看到更多的内容,这样直接使用px是最明智的方案,使用vw,rem等布局手段无可厚非,可是,flex这种弹性布局大行其道的今天,若是若是还用这种传统的思惟去想问题显然是有两个缘由(我的认为px是最好的,可能有大佬,能用vw,或者rem写出精妙的布局,也说不许):

一、为了偷懒,不肯意去作每一个手机的适

二、不肯意去学习新的布局方式,让flex等先进的布局和你擦肩而过

移动端适配流程

1. 在head 设置width=device-width的viewport

2. 在css中使用px

3. 在适当的场景使用flex布局,或者配合vw进行自适应

4. 在跨设备类型的时候(pc <-> 手机 <-> 平板)使用媒体查询

5. 在跨设备类型若是交互差别太大的状况,考虑分开项目开发

写在最后

疫情期间有了跳槽的想法,问到移动端布局方面,虽然勉强能回答上来,可是老是支支吾吾,仿佛不是很了解,故而,发下宏愿,梳理移动端适配,帮助后来人后来者居上!

相关文章
相关标签/搜索