You need to know the mobile terminal development knowledge

Different mobile development and PC-side development, may experience a variety of unexpected problems, especially in mobile terminal application start-up years; With the rapid development of mobile Internet, some problems have been well supported, such as 1 pixel border problems. Of course, to better address the mobile side, we need to have the relevant knowledge of the field of mobile end, the following is said.

dpr device pixel ratio

First talk about, this dpr just have to move the end, pc end there, but the cause of the problem some mobile terminals is generated and solutions becomes more important, such as 1-pixel problem. First look at several concepts:

  1. 物理像素(physical pixel)

    A physical display pixel is the smallest physical unit on a display device, each pixel has its own physical color and brightness values. For example iphone6 ​​phone screen is 750 * 1334 pixels of physical

  2. 设备独立像素(density-independent

    Independent pixel density devices called independent pixels, can also be called logical pixel, the dummy pixel pixel css procedure as used, it can be understood as a point display coordinate system of the apparatus;

  3. 设备像素比dpr(device pixel ratio)

    Than the device pixels, referred DPR, defines the correspondence relationship between the physical device independent pixel and the pixels, a concrete correspondence is calculated as follows:

    dpr = 物理像素 / 设备独立像素

    Dpr calculated above refers x or y direction as one direction, the same value both dpr; dpr obtaining program as follows:

    • js get dpr usewindow.devicePixelRatio

    • use css get dpr-webkit-device-pixel-radio

    IPhone6 e.g., high 375 * 667 device width, can be understood as individual pixels (i.e. pixels css) apparatus; dpr which is 2, then the physical width and height of each pixel corresponding to * 2, i.e. 750 * 1334; that is a logical pixel , the x-axis and y-axis are required to display two physical pixels, a picture is worth a thousand words, as shown:

    from the above described line can be known, css is 1px 1px does not mean a physical display device, which leads to the development of mobile design physical division of the design of pixel 1px, css value converted into 1 / dpr, which may be small value, which low version android (<= 4.4) and ios (<= 8) in the system will be automatically converted to 0, which is the mobile end of the common 1px pixel problem; the following will give specific solutions.

viewport

Did move side development of the students may be familiar with the following html meta tags:

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

This is used to control the mobile terminal viewportarea is how the show, it is necessary to understand them.

viewport understand

In the PC browser, viewport is actually viewable area of the browser, but on mobile devices issue is more complicated, viewport is not limited to the size of the viewable area of the browser, the area may be larger than the visual browser, it may smaller than the browser viewing area; but because the mobile side of the screen compared to the pc too narrow for normal display site for the PC end design in the mobile terminal, the default viewport on the mobile end device in the case are to be larger than the browser vision area, typical values 980pxmay have other values, determined according to the different apparatus; because viewport area larger than the visual browser, the browser will be horizontal scroll bar.

Two things to note:

  1. Html tag page width is relative to the size of the viewport.

  2. PC side is the browser viewport size of the visible region; default viewport is moving end 980px, may be set according to the custom meta tags.

About viewport theory, there is a foreign person ppk this have done a more in-depth research, specifically refer to their written three articles , , . It will be understood viewport is divided into three levels:

  • layout viewport

    Layout window, the page layout viewport true, it may be greater than the width may be smaller than the width of the viewable area of ​​the browser, for greater than a viewable area of ​​the browser (such as the default viewport 980px or custom settings of viewport) of the viewport, only by scrolling the browser scroll bar to show its contents.

  • visual viewport

    Visible window, mobile browser visible size of the region, a width and a certain width of the display screen of the mobile device, scaled to equal only in the case where an initial-scale.

  • ideal viewport

    Idealized window, it does not have a fixed size, having a width of a mobile device screen width, which is the most suitable for the mobile device viewport. Next page set idealized window regardless of the resolution of the screen, the user does not need to zoom and horizontal scroll bar will be able to properly view the content of the website to ensure that pages of text, images, etc. perfect size presented to the user.

A picture is worth a thousand words, to borrow a few online map to illustrate the specific differences:

The above two figures is well understood, the following two comparison chart, the importance of ideal viewport experience for site users, users do not have to scroll or zoom can achieve excellent experience effect.

With control viewport meta tags

Use <meta name="viewport" content="xxx">tags to control the size of the viewport is first introduced by Apple in its safari browser viewport purpose is to solve the problem of mobile devices. Later Andrews and major browser vendors have followed suit, introducing its support for the viewport.

viewport by metacontrolling the size of a page viewport label, the specific form is as follows:

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

Which width=device-widthsuggests that it is provided apparatus the viewport width wide, which may also set specific logical pixel value, such as 980.

Related viewport meta tag value of the content of the six properties, which may be used at the same time, also be used alone may also be used in combination, as follows:

width Setting layout viewportwidth is a positive integer, may also be a device-width
height Setting layout viewportwidth is a positive integer, rarely used
initial-scale The initial scale value is set page, is a number, may be decimals
minimum-scale The minimum scale value of the page, is a number, it may be decimals
maximum-scale Page maximum scaling value, is a number, the decimal
user-scalable Whether to allow page zoom, is "no" or "yes", no not allowed, yes allowed

Two things to note:

  1. user-scalable=no禁止缩放在ios>=10系统的safari下有兼容问题,具体可以看禁止页面缩放meta标签兼容性问题这部分

  2. meta属性中initial-scale的缩放是相对于ideal viewport来进行的

这样通过meta标签很容易设置页面layout viewport为移动设备屏幕宽度(它也是ideal layout)即:

<meta name="viewport" content="width=device-width">

上面这种方式是最直接也是最轻易想到的设法,但是还可以使用initial-scale来达到同样的效果,即:

<meta name="viewport" content="initial-scale=1">

简单解释下,initial-scale表示页面初始缩放值,其缩放是相对于ideal viewport的来说的,为1表示不缩放,那么其layout viewport的宽度就是ideal viewport的宽度,也就是移动设备屏幕的宽度。

既然二者都可以设置layout viewport的宽度,那么二者同时设置且值不相等会怎样呢?答案是:

浏览器会以二者中值较大的那个为准

可能读者会有新的疑惑,在设置layout viewport为屏幕宽度时,经常看到的是二者都写上,为什么呢?答案是:

一个是兼容性的考虑,另一方面解决某些设备横竖屏不分导致通通以ideal viewport的宽度为准的问题

viewport的缩放

上面提到,meta中的initial-scale是相对于ideal viewport进行缩放的,该属性的作用:

initial-scale用来确定visual viewport即浏览器可视区域宽度大小

阿里早期的iphone/ipad下的自适应布局解决方案flexible就是利用initial-scale来解决的。

有人可能会有疑问,移动端浏览器可视区域宽度不就是移动设备屏幕的宽度么?其实我们这里所说的可视区域宽度是逻辑意义上的宽度,而非实际真实的宽度,例如iphone4的320px屏幕宽度,initial-scale放大2倍,那么可视区域的逻辑大小变成了160px,可以通过查看页面html元素的宽度测试。

其实visual viewport与ideal viewport的关系如下:

visual viewport = ideal viewport / initial-scale

在iphone/ipad下,在没有指定initial-scale的情况下,无论你怎么设置layout viewport宽度,它会根据上面的计算关系,自动计算当前页面的inital-scale值以保证layout viewport宽度在缩放后就是浏览器可视区域的的宽度,即inital-scale = ideal viewport宽度 / visual viewport宽度(等于layout viewport宽度)

例如,iphone6情况下默认的layout viewport为980px,那么当前缩放值inital-scale=375 / 980。

需要说明一下的是:在设置了initial-scale的情况下,这个自动计算的值就不起作用了。

移动适配方案

移动端设备不同,其屏幕大小也不尽相同,那么针对特定移动设备的页面设计ui怎么在不同移动设备上因设备不同而自适应屏幕展示呢。一般常见的解决方案有rem和vw/vh。下面就来说说。

rem适配

rem是一个相对单位,相对于<html>font-size来说的;那么参与页面布局的单位使用rem而不是px,这样我们只需控制不同设备下网页<html>font-size即可做到页面的自适应。

可以像flexible一样将移动屏幕宽度100等份,每份为a,同时1rem认定为10a;例如750px的设计稿来说,这样的话:

1a = 750px / 100 = 7.5px
1rem = 10a = 75px

实现代码如下:

(function (doc, win) {
var docEl =doc.documentElement,
    resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
    recalc = function () {
      var width = docEl.getBoundingClientRect().width;
      if (!width) return;
      docEl.style.fontSize = (width / 100)*10 + 'px';
    };

  if (!doc.addEventListener) return;
  win.addEventListener(resizeEvt, recalc, false);
  recalc();
  // hack兼容某些特殊机型
  doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);

另外,我们也可以基于特定的设计稿尺寸来计算其他移动设备下的font-size,例如基于750px的设计稿,我们假设其font-size为40px,那么其他设备下font-size的计算关系式:

\[ 750/40 = 设备屏幕宽/fontsize \]

对应的核心转换代码即: docEl.style.fontSize = (width / 750)*40 + 'px'

VW适配

首先要知道vw和vh的概念代表什么,它也是相对单位,相对于屏幕的宽高而言的。

100vw = ideal viewport 宽

100vh = ideal viewport 高

跟rem类似,我们可以使用vw单位作为css的唯一单位,这样所有元素基于vw来布局;基于特定设计稿的尺寸来转换vw单位,我们使用stylus预编译函数来进行转换:

$vw_base = 375
vw(px) {
   (px/$vw_base) * 100vw
}

然后无论是文本还是布局高宽、间距等都使用 vw 作为 CSS 单位,如

.container
  padding: vw(15) vw(10) vw(10)
  height: vw(40)

vw+rem结合适配

单纯的vw适配在视口缩放时尤其是缩小时有些小瑕疵,因为vw是利用视口单位实现的布局,依赖视口的大小而自动缩放,也就失去了最大最小的宽度限制。一种比较好的解决方法是使用vw与rem配合来进行适配,即:

页面需要适配的元素使用rem为单位,而的font-size值是根据vw来设定的,但是该font-size值需要限制最大最小值。

具体的stylus代码如下,也可以参考这个demo猛戳

$fontsize = 75 // 将屏幕分成10份
$base = 750 // iphone6 750作为基数
rem(px) {
    (px/$fontsize) * 1rem
}

html 
  font-size: ($fontsize / $base) * 100vw //font-size以vw为单位
  // 通过medai query限制根元素的最大值最小值
  @media screen and (max-width: 320px) {// 页面宽度<=320时生效
      font-size: 64px
  }
  @medai screen and (min-width: 540px) { // 页面宽度>=540时生效
      font-size: 108px
  }

媒体查询media query适配

通过类似如下形式来实现适配:

/* 大于1200px */
@media screen and (min-width:1200px){}
/* 大于等于960px,小于1200px */
@media screen and (min-width: 960px) and (max-width: 1199px){}
/* 大于等于768px,小于960px */
@media screen and (min-width: 768px) and (max-width: 959px){}
/* 大于等于480px,小于768px */
@media only screen and (min-width: 480px) and (max-width: 767px){}
/* 小于479px */
@media only screen and (max-width: 479px){}

该方式比较简单,成本低,但是代码量大,比较臃肿,维护不方便,不推荐该方式。

阿里flexible适配

该方案随着viewport单位 得到众多浏览器的兼容支持已逐渐不推荐使用了,它主要是为了解决iphone系列适配问题;虽然官方已不推荐使用,但是其思想还是值得借鉴学习的,主要表现下面三个方面:

  • 根据dpr的值来修改<meta>viewport的值实现移动端1px的问题

  • 根据dpr的值来修改<html>font-size值,使用以rem为单位值来等比例缩放

  • 使用hack手段用rem模拟vw特性

对应第一点,它通过hack手段来根据设备的dpr值相应改变<meta>标签中的viewport的值:

<!-- dpr = 1-->
<meta name="viewport" content="initial-scale=scale,maximum-scale=scale,minimum-scale=scale,user-scalable=no">
 <!-- dpr = 2-->
<meta name="viewport" content="initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no">
 <!-- dpr = 3-->
<meta name="viewport" content="initial-scale=0.3333333333,maximum-scale=0.3333333333,minimum-scale=0.3333333333,user-scalable=no">

这样,iphone系统的不同设备下页面达到的效果是使css 1px像素与物理1px像素相同;然后,flexible使用rem作为布局单位实现适应布局。关键基本代码如下:

// 设置meta的viewport内容进行缩放
var isAndroid = win.navigator.appVersion.match(/android/gi);
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
    // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
    if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
        dpr = 3;
    } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
        dpr = 2;
    } else {
        dpr = 1;
    }
} else {
    // 其他设备下,仍旧使用1倍的方案
    dpr = 1;
}
scale = 1 / dpr;

// 确定html的font-size值
var width = docEl.getBoundingClientRect().width;
if (width / dpr > 540) {
    width = 540 * dpr;
}
var rem = width / 10; // 屏幕均分100份,每份为a,1rem为10a
docEl.style.fontSize = rem + 'px';

1px边框问题及解决方案

产生1px边框的问题其实归结三点:

  • 1px的css逻辑像素不等于1px的物理像素

  • ios<8以及Android<=4.4以下的浏览器处理0.5px时会转化为0

对于1px边框问题的解决,flexible能完美的解决,思路见上面分析的;除此之外还有什么方式,其实网上有很多方法,但是还是列一下思路:

  1. 用border-image来实现

    使用一张图片来充当border,图片形式是3x3,如下:

    .border {
        border-width: 1px;
        border-image: url(border.png) 2 repeat;
    }

    缺点:改边框颜色时要修改图片,不灵活

  2. 用背景渐变来实现

    设置1px的渐变背景,50%有颜色,50%透明

    .border {
        background-image: linear-gradient(180deg, green, green 50%, transparent 0);
      background-size: 100% 1px; /* 背景宽度100%,高度1px */
      background-repeat: no-repeat;
      background-position: bottom;
    }

    缺点:维护过多代码,圆角没法实现

  3. 用box-shadow模拟边框来实现

    .border {
        border: none;
        height: 100px;
        width: 100%;
        box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.5);
    }

    缺点:颜色不好处理,有阴影出现

  4. 用伪类+transform来实现

    比较推荐的方法,原理是把原先元素的border去掉,然后利用:before或者:after重做border,并把transformscale缩小一半,原先元素相对定位,伪元素模拟的border采用绝对定位。

    .border {
        position: relative;
        border: none;
    }
    .border:after {
        content: ' ';
        position: absolute;
        left: 0;
        background: #666;
        width: 100%;
        height: 1px;
        tranform: scaleY(0.5);
        transform-origin: 0 0;
    }

参考文献

Guess you like

Origin www.cnblogs.com/wonyun/p/11932142.html