移动端基础
基本概念
屏幕尺寸
屏幕斜对角的长度
像素
像素可以分为物理像素和逻辑像素。逻辑像素 = 设备独立像素 = css像素
1,物理像素
屏幕成象的最小单位,也就是厂家在生产显示设备时就决定的实际点的个数,屏幕中的分辨率,其实都是物理像素,也称为设备像素。
2,css像素
网页设计中用到的一种单位,是一个相对单位,相对的是设备像素。 在 CSS 中使用的 px 都是指 CSS 像素。不考虑缩放情况下,1个 CSS 像素等于1个设备独立像素。
CSS 像素又称为虚拟像素,是一个相对单位,单位为 px。
CSS 像素不能直接跟现实中的长度单位换算。
CSS 像素主要用在 CSS 与 JS 中控制元素的大小与位置。也是web开发者使用的最小单位。
3,设备独立像素
- 是一个长度计量单位。
如果我们画一条线,长度是20px,如果都以物理像素作为度量单位,那么在显示器看起来正常,在iphoneX上就会非
常小,这不是我们想要的结果,为了解决这个问题,还需要一个新的度量单位,这个度量单位必须是与设备无关的,
采用这个单位,无论在何种设备上,相同长度的线看起来都应该差不多,这就是设备独立像素,我们在css中用的是
css像素,其实就是一种设备独立像素.
- 调整电脑显示器的分辨率,即调整了设备独立像素
物理像素是在出厂时就决定的,但是设备独立像素其实是可调的。大家用电脑的时候,应该都试过调整分辨率,此时调
整的实际就是设备独立像素
- 设备独立像素也是手机屏幕的一个参数,由手机制造商决定。
例如IPhone 6 的设备独立像素为 375 * 667。iphon6的屏幕分辨率是750*1334(物理像素)
- 逻辑像素的单位是pt
4,位图像素
- 位图图像亦称为点阵图像或栅格图像,是由单个的像素点组成的。放大后会失真。(png jpeg jpg gif)
- 图片的最小单位,只有当图片像素和物理像素1:1的时候,图片才能清晰完美的展示
5,像素之间的关系
1. 在一个标准的显示密度下(普通屏),一个 CSS 像素对应着一个设备像素,高清屏幕下一个 CSS 像素 等于 N
个物理像素。
2.页面不缩放的情况下,CSS 像素 == 独立设备像素== 位图像素。
3. 不管何种设备,一般都满足:设备独立像素 <= 物理像素
CSS 中的 1px 并不等于设备的 1px
对于前端来说,在高清屏出现之前,前端代码的 `1px` 即等于手机物理像素点的 `1px`。但有了 dpr 的概念之
后,由于前端代码中的使用的是 CSS 像素,手机会根据 dpr 换算成实际的物理像素大小来渲染页面。比如
iPhone6 的设备像素比 `dpr = 2` ,相当于一个 CSS 像素等于两个物理像素,即 `1px` 由 2个物理像素点
组成。
屏幕分辨率
- 屏幕分辨率是指纵横向上的像素点数,单位是px;
- PPI:是图像分辨率,在图像中每英寸所表达的像素数目;
- DPI:是打印分辨率,每英寸所表达的打印点数
4,设备像素比dpr(devicePixelRation)
- 计算公式:dpr = 设备物理像素 / 设备独立像素
- scale 和 dpr的关系是倒数。scale是屏幕拉伸比,也就是视口上的initial-scale , maximum-sacle 等属性。
- 可以通过
window.devicePixelRatio获取屏幕像素比,注意这个方法有一定的兼容性。通常使用这个值是多少就是几倍屏,iPhone6/7/8中devicePixelRatio的为2,devicePixelRation并不一定是整数,也有可能是1.5,2.25这些小数值
4,dip
设备独立像素的简写,dip和dp是一个意思
view port
1,layout viewport (布局视口)
- 一般移动设备的浏览器都默认定义一个虚拟的布局视口(layout viewport),用于解决早期的页面在手机上显示的问题。视口大小由浏览器厂商决定,大多数移动设备的布局视口大小为 980px。
- 可以通document.documentElement.clientWidth,document.documentElement.clientHeight获取对应值
2,visual viewport(视觉视口,虚拟视口)
- 视觉视口就是用户可见的区域
- 可以通过window.innerWidth,window.innerHeight获取对应值
- 不缩放的情况下,视觉视口宽度 == 布局视口宽度
3,ideal viewport (完美视口)
- 用户不需要缩放和滚动条就能看到网站的全部内容。针对移动端的设计稿更容易开发。
- 获取理想视口的宽高:window.screen.width/height
- 一般可以通过如下设置,来达到完美视口效果。
<meta name="viewport" content="width=device-width, height=device-height,
initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no />
移动端适配方案
响应式布局涉及到的方式大概有以下几种方式,这些方式根据页面的实际要求可以混用: 百分比,flex/grid,媒体查询,rem/em,vw/vh, viewport+rem
这里只介绍一种比较复杂且在移动端比较适用的方案:
1,viewport+rem+固定html的font-size(使用媒体查询设置不同区间的font-size大小)
浏览器默认的html的font-size是16px,设置font-size为62.5%也就是10;此时1rem = 10px,换算可得1px = 0.1rem,我们就可以很容易的将设计图中的单位转换为rem单位。设计完成之后在375屏幕下是完全合适的,在更大的屏幕下,想要对应的数据显示的更大,即可以使用媒体查询设置对应的html的font-size。对应的使用了rem的数据也会随之变化。
//1,设置ideal viewport
<meta name="viewport" content="width=device-width, initial-scale=1.0">
//2,设置不同区间的html font-size
html {
font-size: 62.5%;
}
@media screen and (min-width:400px) {
html {
font-size: 64% !important;
}
}
//3,根据设计图计算对应的rem(注意,需要先将设计图的px/2得到适配375屏幕的尺寸,然后根据得到的像素计算出对应的rem值)
.contest-info-container {
width: 34.5rem;
height: 8rem;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: 12.1rem;
}
2,viewport+rem+根据屏幕宽度动态设置font-size
(1)ui像素/css像素= 750 / window.innerWidth; (2)将html的font-size设置为:window.innerWidth/7.5 即 1rem = (window.innerWidth/7.5)px 那么也就可计算出1px = (7.5/window.innerWidth)rem; (3)由1和2可以得出最终css像素 = 设计稿尺寸大小 /100rem (4)此方式不用媒体查询,因为是动态设置html的font-size。
//1,设置ideal viewport
<meta name="viewport" content="width=device-width, initial-scale=1.0">
//2,根据不同的屏幕尺寸动态计算对应的html的font-size:
document.documentElement.style.fontSize = window.innerWidth / 7.5 + "px";
//按照ui设计书写样式
最终样式长度 x = 设计稿元素尺寸大小 / 100rem;
关于移动端设计的一些问题?
1,为什么移动端的设计图一般都是750px;
自iphone6-iphone8,他们的物理分辨率都是750*1334px,这几代现在依旧受大家的喜爱,750px的设计标准,也慢慢成为移动端的设计标准。而且iphone6的设备独立像素是375,375/2就可得到,很便于移动端尺寸适配的计算。其他手机的像素和375也不会太大,所以也便于其他移动端设备的适配。
2,移动端之经典问题1px边框出现原因以及解决方案?
在 PC 端浏览器的最小识别像素为 1px,所以在开发阶段,当在开发者工具上进行页面调试时,可以看到即便代码中是 0.5px ,但默认会被浏览器识别并渲染为 1px。所以在浏览器看来总是偏粗了。如果你习惯用 PC 端的页面来进行视觉走查,那么结果可想而知...
由表格可看出,不同手机计算的“1px”大小差别很大,而且手机本身对小数点的处理情况就存在较大的兼容性问题。
IOS8+ 系列都已经支持 0.5px 了,可以借助媒体查询来处理,但是安卓手机对小数像素的表现形式却各不相同。网上关于不同型号手机浏览器对小数点的处理情况的资料较少,只知道在一些低版本的系统里,0.5px 将会被显示为 0px;有的能够画出半个像素的边,有的大于 0.55px 当成 1px,有的大于 0.75px 当成 1px,难直接实现适配的。
目前的实现方案都离不开以下三种。
1.使用伪元素 + CSS3``缩放的方式
// 通过伪元素实现 0.5px border
.border::after {
content: "";
box-sizing: border-box; // 为了与原元素等大
position: absolute;
left: 0;
top: 0;
width: 200%;
height: 200%;
border: 1px solid gray;
transform: scale(0.5);
transform-origin: 0 0;
}
// 通过伪元素实现 0.5px 细线
.line::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 200%;
height: 1px;
background: #b3b4b8;
transform: scale(0.5);
transform-origin: 0 0;
}
// dpr适配可以这样写
@media (-webkit-min-device-pixel-ratio: 2) {
.line::after {
...
height: 1px;
transform: scale(0.5);
transform-origin: 0 0;
}
}
@media (-webkit-min-device-pixel-ratio: 3) {
.line::after {
...
height: 1px;
transform: scale(0.333);
transform-origin: 0 0;
}
}
为了只缩放 border 1px 的粗细,而保证 border 的大小不变。如果直接 scale(0.5) 的话 border 整体大小也会变成二分之一,所以先放大 200%(放大的时候 border 的粗细是不会被放大的)再缩放,就能保持原大小不变了。
2.使用 动态 viewport + rem 布局 的方式(即 Flexible 实现方案)
第二种实现方案是采用动态设置 `viewport + rem` 布局,该方案其实是参考了阿里早期开源的一个移动端适配
解决方案 `flexible` ,本文进行了一些改进。该方案不仅解决了移动端适配的问题,同时也较好的解决
了 `1px` 的问题。
3.新方案:使用 vw 单位适配方案(将来推荐的一种方案,但目前项目中没有实际应用,故本文不做讨论)
简单案例如下:
<head>
<meta
name="viewport"
content="width=device-width,user-scalable=no,initial-scale=1,
minimum-scale=1,maximum-scale=1,viewport-fit=cover"
/>
<script type="text/javascript">
// 动态设置 viewport 的 initial-scale
var viewport = document.querySelector("meta[name=viewport]");
var dpr = window.devicePixelRatio || 1;
var scale = 1 / dpr;
viewport.setAttribute(
"content",
"width=device-width," +
"initial-scale=" +
scale +
", maximum-scale=" +
scale +
", minimum-scale=" +
scale +
", user-scalable=no"
);
// 计算 rem font-size
var clientWidth =
document.documentElement.clientWidth || document.body.clientWidth;
clientWidth > 750 && (clientWidth = 750);
var ft = (clientWidth / 7.5).toFixed(2); // 以750设计稿为例
document.documentElement.style.fontSize = ft + "px";
</script>
</head>