英寸

一般我们都用英寸来描述设备的物理尺寸,例如电脑: 17英寸、13英寸,手机: 6.5英寸、4英寸;我们说一个手机6.5英寸,其实指的是屏幕对角线的长度
1 英寸 = 2.54 厘米

Px 像素

一个小正方形的方块,每一个像素都具备 颜色 和 特定的位置;像素并不是个绝对单位

分辨率

屏幕具体由多少个像素组成,并不是分辨率高,就说明屏幕清晰的,这个还需要考虑尺寸问题

PPI

像素点和清晰度的关系,即每英寸包含的像素点

物理像素

上面我们描述的这个像素,我们称为物理像素 设备像素 UI像素,即设备真实存在的物理单元

同样尺寸的两台手机: 低分辨率手机 320 480 和 高分辨率手机 640 960
高分辨率手机的两个像素点的大小 = 低分辨率手机的一个像素点的大小
设定相同的像素点,在分辨率高的屏幕上,看上去会更小;这就是为什么同样大小的元素,在 PC 和 移动端,显示的有差别的原因移动端下的像素点,比 PC 的像素点要更小

那为什么 Mobile 70 70 看着比 PC 80 80 还要大呢?

Retina 视网膜屏幕

Retina 视网膜屏幕
我们的手机屏幕尺寸是非常多的,但是即使尺寸很多分辨率不同,我们会发现一个很神奇的事情,就是显示上面好像都差不多

视网膜屏幕: 低分辨率手机 1 的大小 = 高分辨率手机 2 * 2 的大小
这样屏幕更精致,看上去也不会有大小的变化

设备独立像素

又称逻辑像素 CSS像素

设备像素比 = 物理像素 / 设备独立像素 = window.devicePixelRatio

iphone6
物理像素 750 * 1334
设备像素比 2
设备独立像素 375 * 667

当然也有设备例外:

iPhone6 plus
物理像素 1080 * 1920
设备像素比 3
设备独立像素 414 * 736

说好的 设备像素比 = 物理像素 / 设备独立像素 呢

(414 736 ) 3 = 1242 * 2208

放心,手机会自动把 1242 2208 的设备独立像素,塞进 1080 1920 的物理像素中

大家也可以看到 iphone6 是贴合我们像素比的要求的,所以一般我们拿到的手机设计图,就是 750 * 1334 的

viewport 视口

  • layout viewport 布局视口
    网页布局的基准窗口,在这里只考虑布局,也就是不会有非布局的内容,例如滚动条、菜单栏
    而在移动端,布局视口有一个默认值980px,这保证了PC网站可以在手机上显示(尽管丑丑的)
    document.documentElement.clientWidth
  • visual viewport 视觉视口
    用户视觉上看到的真实区域vw vh,包括滚动条
    window.innerWidth
  • ideal viewport 理想视口
    其实就是我们说的设备独立像素,当 布局视口 和 理想视口 一致的时候,那结果就是一样的了
    window.screen.width

移动端: 视觉视口 = 布局视口
PC端: 布局视口不包括滚动条

想要更改布局视口,利用 meta 标签的 viewport 来进行设置

属性 描述
width 正整数 或 device-width 以像素为单位,定义布局视口的宽度
height 正整数 或 device-height 以像素为单位,定义布局视口的高度
initial-scale 允许是小数 定义页面初始缩放比例
minimum-scale 0.0 - 10.0 定义缩放的最小值
maximum-scale 允许是小数 定义缩放的最大值(ios10 & ios10+ 无效)
user-scalable yes / no 设置是否允许缩放,同上无效
  • ios10 及 ios10+ 设置最大缩放值无效
  • initial 和 width 是有冲突的
  • initial 和 最小值 是一致的
  • 部分安卓机型,不接受 width = 具体数值 这样的操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">

<script>
const html = document.documentElement;
const width = html.clientWidth;
// html.style.fontSize = 10vw;
html.style.fontSize = width / 10 + 'px';
</script>

<script>
function setPageFontsize() {
// window.devicePixelRatio || 2
const docEl = document.documentElement
const clientWidth = docEl.clientWidth
document.documentElement.style.setProperty('--vh', (window.innerHeight / 100) + 'px')
if (!clientWidth)
return
const isLandscape = window.matchMedia('(orientation: landscape)')
if (isLandscape.matches) {
const horizontalFontsize = 100 * (clientWidth / 1624)
docEl.style.fontSize = horizontalFontsize + 'px'
} else {
/*
750 : 375
100 : 50
*/
let verticalFontsize = 100 * (clientWidth / 750)
if (verticalFontsize > 80) {
verticalFontsize = 80
}
docEl.style.fontSize = verticalFontsize + 'px'
}
}
(function (doc, win) {
!function f() {
doc.body ? doc.body.style.fontSize = '16px' : doc.addEventListener('DOMContentLoaded', f)
}()
const resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize'
setPageFontsize()
setTimeout(function () {
setPageFontsize()
}, 100)
if (!doc.addEventListener)
return
win.addEventListener(resizeEvt, setPageFontsize, false)
doc.addEventListener('DOMContentLoaded', setPageFontsize, false)
win.addEventListener('pageshow', function (e) {
e.persisted && setPageFontsize()
})
}
)(document, window)
</script>

响应式设计

  • 百分比

  • rem

  • viewport

    1
    2
    3
    4
    5
    6
    7
    <script>
    const meta = document.createElement('meta');
    const scale = 1 / window.devicePixelRatio;
    meta.name = "viewport";
    meta.content = "initial-scale=" + scale + ", shrink-to-fit=no, minimum-scale=" + scale + ", maximum-scale=" + scale + ", user-scalable=no";
    document.head.appendChild(meta);
    </script>
  • media-query

    1
    2
    @media screen and (orientation: portrait) {}
    @media screen and (orientation: landscape) {}
  • vw vh
    vmin 选取 vw 和 vh 中较小的
    vmax 选取 vw 和 vh 中较大的

请问 px % em rem vw/vh 的区别?

  • px 像素,基本单位
  • % 相对于父元素的尺寸
  • em 相对于自身元素的 font-size;首行缩进text-indent: 2em
  • rem 相对于根元素 html 的 font-size
  • vw 屏幕宽度的 1%
  • vh 屏幕高度的 1%

云里雾里

东西反正就是这么个东西吧😅
👀只可意会 不会言传
继续戳 👈

避坑指南

iphoneX 刘海屏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<meta name="viewport" content="viewport-fit=cover">

<style type="text/css">
body {
/* 小于 IOS11.2 版本生效 */
padding-bottom: constant(safe-area-inset-bottom);
/* 大于 IOS11.2 版本生效 */
padding-bottom: env(safe-area-inset-bottom);
}
</style>

<!-- 针对 IOS9,超出屏幕宽度的内容,也会缩放显示到屏幕 -->
<meta name="viewport" content="shrink-to-fit=no">

屏幕旋转

  • safe-area-inset-lef 设置左侧安全区
  • safe-area-inset-right 设置右侧安全区
  • safe-area-inset-top 设置顶部安全区
  • safe-area-inset-bottom 设置底部安全区

1px 边框

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.border_1px::before {
content: '';
position: absolute;
top: 0;
height: 1px;
width: 100%;
background-color: #000;
transform-origin: 0% 0%;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
.border_1px::before {
transform: scaleY(0.5);
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 3) {
.border_1px::before {
transform: scaleY(0.33);
}
}

/* 1px 圆角边框 */
border-radius_1px {
border-radius: 20%;
/* border: 1px solid #d9d9d9; */
box-shadow: 0 0 0 0.5px #d9d9d9;
}

Retina屏 图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.avatar {
background-image: url(avatar_1x.png);
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
.avatar {
background-image: url(avatar_2x.png);
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 3) {
.avatar {
background-image: url(avatar_3x.png);
}
}

/* 兼容 */
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 2dppx) {}

滚动穿透

移动端的网站,经常会有一些弹出框出现,这样的弹出框,在上面滑动,会导致我们后面的整个页面发生移动,这个问题怎么解决呢?

1
2
3
4
5
6
body {
position: fixed;
width: 100%;
top: 0px; /* js 动态设置 */
height: auto;
}

键盘唤起

当底部根据页面进行fixed定位的时候,键盘弹出一瞬间,fixed会失效,变成类似absoult,让main的内容无滚动,就不会连带fixed一起动了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
main {
padding: 2rem 0;
/* height: 2000px; */
position: absolute;
top: 60px;
bottom: 60px;
overflow-y: scroll;
width: 100%;
-webkit-overflow-scrolling: touch; /* 如丝般顺滑 */
overscroll-behavior: none; /* ios 禁用回弹 */
}

input {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 60px;
background: pink;
}

默认样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* 禁止文本缩放 */
html {
-webkit-text-size-adjust: 100%;
}

/* IOS系统中,链接、按钮等点击会有灰色遮罩 */
a,
input,
button,
textarea {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

/* 去除圆角 */
input,
select,
button {
appearance: none;
-webkit-appearance: none;
border-radius: 0;
}

大开眼界

添加到主屏幕的标题

1
<meta name="apple-mobile-web-app-title" content="标题">

添加到主屏的图标

1
<link href="short_cut_114x114.png" rel="apple-touch-icon-precomposed">

启用 webApp 全屏模式

1
2
3
4
<!-- 删除默认的苹果工具栏和菜单栏 -->
<meta name="apple-mobile-web-app-capable" content="yes">
<!-- 全屏显示 -->
<meta name="apple-touch-fullscreen" content="yes">

禁用手机号码识别

safari会对一些可能是手机号码的数字进行识别,我们可以利用👇的方式,禁止识别

1
<meta name="format-detection" content="telephone=no">

禁用邮箱识别

1
<meta name="format-detection" content="email=no">

开启拨打电话功能

在手机上点击这个链接,可以直接拨打电话

1
<a href="tel:13300000000">13300000000</a>

开启短信发送功能

在手机上点击这个链接,可以跳转去短信页面,给该手机号发送消息

1
<a href="sms:13300000000">13300000000</a>

开启邮箱发送功能

1
<a href="mailto:daibo@daidaibo.com">发送邮件</a>

优先启用最新版本 IE 和 Chrome

1
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">