移动端自适应

移动端适配

解决如何让页面适配各种不同的终端设备,使不同的终端设备都拥有基本一致的视觉效果和交互体验

分辨率(Resolution)

分辨率是指位图图像中细节的精细程度,以每英寸像素(ppi)衡量。
每英寸的像素越多,分辨率就越高。

物理像素(Physical pixels)

一个设备的实际像素数。
所谓的一倍屏、二倍屏(Retina)、三倍屏,指的是设备以多少物理像素来显示一个CSS像素,
也就是说,多倍屏以更多更精细的物理像素点来显示一个CSS像素点。
在普通屏幕下,1个CSS像素对应1个物理像素,而在Retina屏幕下,1个CSS像素对应的却是4个物理像素。

逻辑像素(Logical pixels)

是一种抽象概念。CSS 像素是逻辑像素。
在不同的设备下,一个逻辑像素代表的物理像素数不同。
使用逻辑像素描述尺寸,可以在不同尺寸和密度比的设备上表现出一致的视觉效果。
在具有高密度比的屏幕下,一个逻辑像素对应多个物理像素。

设备像素比(Device Pixel Ratio)

当前显示设备的物理像素CSS 像素之比。

图片或 1px 边框显示模糊?

  1. 图片模糊问题
    理论上,1个位图像素对应于1个物理像素,图片才能完美清晰展示。
    对于dpr=2的Retina屏幕而言, 1个位图像素对应于4个物理像素。
    由于单个位图像素不可以再进一步分割,所以只能就近取色,导致图片看起来比较模糊。
    而在普通屏幕下,如果使用多倍图片(@2x),就会出现一个物理像素点对应4个位图像素点,
    但它的取色也只能通过一定的算法,取某一个位图像素点上的色值。
    肉眼看上去,虽然图片不会模糊,但是会觉得图片有点色差。
    最好的解决办法是:不同的dpr下,加载不同的尺寸的图片。
    如:一个200×300(CSS pixel)的img标签:
    对于dpr=2的屏幕,用400×600的图片,
    这样在Retina屏幕下,位图像素点个数就可以跟物理像素点个数形成 1 : 1的比例,图片自然就清晰了。
  2. 1px 细线问题
    CSS像素为1px宽的直线,对应的物理像素是不同的,可能是2px或者3px,而设计师想要的1px宽的直线,其实就是1物理像素宽。

用媒体查询根据dpr用“伪元素+transform”对边框进行缩放

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.border-1px {
position: relative;
}
@media screen and (-webkit-min-device-pixel-ratio: 2) {
.border-1px:before {
content: " ";
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 1px;
border-top: 1px solid #D9D9D9;
color: #D9D9D9;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}
}

viewport 元标签配置视口

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

tips:
如果不进行 viewport 元标签的设置,可能会导致开发者设定的较小宽度的媒体查询永远不会被使用,因为默认的布局视口宽度为 980px。

现代响应式布局方案

  1. 浮动布局
  2. 百分比布局
  3. Flexbox
  4. CSS Grid
  • flexbox
    更适用于一维布局,一次只能处理一行或一列上的布局;
    尺寸根据其内部内容和可用空间进行增长和缩小

  • CSS grid (IE不支持)
    通过在元素上声明 display:grid 或 display:inline-grid 来创建一个网格容器,
    一旦这样做,这个元素的所有直系子元素将成为网格项目。
    需要同时按照行和列控制布局则使用 CSS Grid
    固定的列宽和行高

1
2
3
4
5
6
7
8
.wrapper {
display: grid;
/* 3列,列宽分别为 200px 100px 200px */
grid-template-columns: 200px 100px 200px;
grid-gap: 5px;
/* 2行,而且行高都为 50px */
grid-template-rows: repeat(2, 50px);
}

媒体查询(Media Queries)

媒体查询允许开发者根据设备类型和特征(如屏幕分辨率或浏览器视口宽度)来按需设置样式。

1
2
3
4
5
6
7
8
9
10
11
12
/* 当浏览器宽度至少在 600px 及以上时 */
@media screen and (min-width: 600px) {
.wrapper {
}
}

/* 当设备 DPR 为2时的样式 */
@media screen and (-webkit-min-device-pixel-ratio: 2) {
.border-1 {
border-width: 0.5px;
}
}

使用相对单位

  • rem
    1rem 等于根元素 html 的 font-size 大小
    通过密集的媒体查询来设置html的font-size

  • vh/vw

使用响应式图片

展示图片时,可以在 picture 元素中定义零或多个 source 元素和一个 img 元素,
以便为不同的设备场景提供图像的替代版本。
从而使得图片内容能够响应不同的设备,避免出现图片模糊或使用过大图片浪费带宽的问题。

source 元素可以按需配置 srcset、media等属性,以便为不同媒体查询范围或像素密度比的设备配置对应的图片资源。
如果没有找到匹配的图像或浏览器不支持 picture 元素,则使用 img 元素作为回退方案。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<picture>
<source
srcset="hzfe-avatar-desktop.png, hzfe-avatar-desktop-2x.png 2x"
media="(min-width: 990px)"
/>
<source
srcset="hzfe-avatar-tablet.png, hzfe-avatar-tablet-2x.png 2x"
media="(min-width: 750px)"
/>
<img
srcset="hzfe-avatar.png, hzfe-avatar-2x.png 2x"
src="hzfe-avatar.png"
alt="hzfe-default-avatar"
/>
</picture>

适配安全区域

手机上常见有圆角(corners)、刘海(sensor housing)和小黑条(Home Indicator)等特征。
为保证页面的显示效果不被这些特征遮盖,需要把页面限制在安全区域范围内。 (viewport-fit=cover)

  1. <meta name="viewport" content="initial-scale=1, viewport-fit=cover" />
  2. 借助环境变量,对元素设置 padding
  • safe-area-inset-left
  • safe-area-inset-right
  • safe-area-inset-top
  • safe-area-inset-bottom
    1
    2
    3
    4
    5
    6
    7
    /* 兼容刘海屏 */
    body {
    /* constant 函数兼容 iOS 11.2 以下*/
    padding-top: constant(safe-area-inset-top);
    /* env 函数兼容 iOS 11.2 */
    padding-top: env(safe-area-inset-top);
    }
查看评论