1. 设备像素、设备独立像素、CSS像素、PPI、devicePixelRatio
1.1 设备像素(物理像素 / 像素分辨率)
- 显示器的最小物理单位(对于一个显示器来说是固定)
- 以手机屏幕为例,iPhone像素分辨率为1125x2436,是指屏幕横向能显示1125个物理像素点,纵向能显示2436个物理像素点
- 通常说的4K显示屏指的是4096x2160
1.2 设备独立像素(dips)
- 比如我们说的“电脑屏幕在2560x1600分辨率下不适合玩游戏,我们把它调成1440x900”,这里的分辨率指的就是设备独立像素
- 可在控制台通过
window.screen.width
/window.screen.height
查看 - 平时我们所说的iPhone X的逻辑分辨率375x812指的就是设备独立像素
- 一个设备独立像素可能包含多个物理像素,包含的越多,显示越清晰
1.3 CSS像素
- 在页面不缩放的情况下,1px的CSS像素 === 1设备独立像素
- 页面放大200%时,页面的设备独立像素依旧不变,放大的是CSS像素。但是此时CSS像素与设备独立像素的关系变化了,1px === 4独立像素(宽x2,高x2)
1.4 PPI
- 指每英寸的物理像素数
- 以尺寸为5.8英寸(屏幕对角线长度)、分辨率为1125x2436的iPhone X为例:
- ppi = Math.sqrt(11251125 + 24362436) / 5.8,值为463ppi
1.5 devicePixelRatio
- 像素比
window.devicePixelRatio
devicePixelRatio
指的是物理像素和设备独立像素的比,即1独立像素由多少物理像素渲染- dpr(device.pixel ratio):设备像素比,设备像素/设备独立像素,代表设备独立像素到设备像素的转换关系,在JS中可以通过
window.devicePixelRatio
获取 window.devicePixelRatio
= 物理像素 / 设备独立像素- iPhone X的
devicePixelRatio
是3
1.6 高清屏图片失真
- 一些像素比较低的图片,在普通显示屏上可以显示,但在高清屏上会出现模糊的现象
- 原因是:假如一张图片,设置宽高是100px,在不同屏幕上,呈现的都是100个设备独立像素的图片,但是对于高清屏来说,100个设备独立像素所需要的物理像素比普通屏多得多
- 1个设备独立像素所含的物理像素越多,显示越清晰;假如普通屏100个设备独立像素需要1W个物理像素点,高清屏得3W个。但是图片本身包含的像素点可能远远达不到3W,这个时候,图片就会拉伸自己的像素点,所以看起来就显得模糊
- 解决办法:高清屏上图片的宽高设小一点,这样所需的物理像素就不用那么多了,屏幕显示图片所需的物理像素越接近图片,图片越清晰
1.7 矢量图永不失真
- 因为矢量图不是一个个像素点显示的,而是
通过给定的坐标数据进行绘制的
,所以不会失真
2. layout viewport和visual viewport
- layout viewport(布局视口)
- visual viewport(视觉视口)和物理像素
- ideal viewport(理想视口)和dip(设备独立像素)
3. viewport缩放适配
- 屏幕的尺寸:
window.screen.width // 设备独立像素
- 浏览器窗口尺寸:
window.innerWidth、window.innerHeight // CSS像素
<!-- meta:vp tab -->
<meta id="viewport" name="viewport" content="width=device-width; init
ial-scale=1.0;maximum-scale=1.0; user-scalable=no;">
移动前端中常说的viewport
(视口)就是浏览器显示页面内容的屏幕区域:
width
:控制viewport
的大小,可以指定一个值,比如600,或者特殊的值,比如device-width
为设备的宽度(单位是缩放为100%的CSS像素)height
:和width
相对应,指定高度initial-scale
:初始缩放比例,也就是当页面第一次load
的时候缩放比例maximum-scale
:允许用户缩放到最大比例minimum-scale
:允许用户缩放到最小比例user-scalabel
:用户是否可以手动缩放
4. 媒体查询@media
语法:@media 媒体类型 逻辑操作符 (媒体属性) {样式代码}
4.1 逻辑操作符
and
:操作符用来把多个媒体属性组合起来,合并到同一条媒体查询中。只有当每个属性都为真时,这条查询的结果才为真;@media all and (min-width: 700px) and (orientation: lanscape) {...}
not
:操作符用来对一条媒体查询的结构进行取反;@media not all and (monochrome) {...}
only
:操作符表示仅在媒体查询匹配成功时应用指定样式,可以通过它让选中的样式在老式浏览器中不被应用;@media only screen and (max-width: 1000px) {...}
4.2 媒体属性
width
|min-width
|max-width
height
|min-height
|max-height
device-width
|min-device-width
|max-device-width
device-height
|min-device-height
|max-device-height
aspect-ratio
|min-aspect-ratio
|max-aspect-ratio
device-aspect-ratio
|min-device-aspect-ratio
|max-device-aspect-ratio
color
|min-color
|max-color
color-index
|min-color-index
|max-color-index
monochrome
|min-monochrome
|max-monochrome
resolution
|min-resolution
|max-resolution
scan
|grid
4.3 横竖屏
@media (orientation: portrait) {竖屏}
@media (orientation: landscape) {横屏}
5. vw弹性适配
vw
:1vw
等于视口宽度的1%vh
:1vh
等于视口高度的1%vmin
:选取vw
和vh
中最小的那个vmax
:选取vw
和vh
中最大的那个- 视口单位区别于%单位,视口单位是依赖于视口的尺寸,根据视口尺寸的百分比来定义的;而%单位则是依赖于元素的祖先元素
6. 动态rem适配
- 相对长度单位,相对于根元素(HTML元素)
font-size
计算值的倍数 - 根元素HTML默认的
font-size
为16px
- 为了方便计算,我们一般给父元素的font-size设置为
100px
- 移动端适配rem && vw计算工具:www.jq22.com/demo/jquery…
// 针对750的设计稿
function refreshRem() {
var desW = 750,
winW = document.documentElement.clientWidth,
ratio = winW / desW;
document.documentElement.style.fontSize = ratio * 100 + 'px';
}
refreshRem();
window.addEventListener('resize', refreshRem);
7. 弹性flex适配
Flex是Flexible Box的缩写,意为“弹性布局”,用来为盒装模型提供最大的灵活性。
7.1 flex布局的基本概念
采用Flex布局的元素,称为Flex容器(flex container),简称“容器”。它的所有子元素自动称为容器成员,称为Flex项目(flex item),简称“项目”。
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。
7.2 容器的属性
flex-direction
flex-wrap
flex-flow
justify-content
align-items
align-content
7.2.1 flex-direction
设置主轴的方向
row
:主轴的方向是水平,从左到右column
:主轴的方向是垂直的,从上到下row-reverse
:主轴的方向是水平,从右到左column-reverse
:主轴的方向是垂直的,从下到上
7.2.2 flex-wrap
wrap
:换行nowrap
:不换行(默认)wrap-reverse
:换行,不过第一行在最下面
7.2.3 flex-flow
flex-flow
属性是flex-direction
属性和flex-wrap
属性的简写形式,默认值为row nowrap
7.2.4 justify-content
属性定义了项目在主轴上的对齐方式
justify-content: flex-start
| flex-end
| center
| space-between
| space-around
| space-evenly
7.2.5 align-items
align-items
属性定义项目在交叉轴上如何对齐
align-items:flex-start
| flex-end
| center
| baseline
| stretch
stretch
(默认值):如果项目未设置高度或者设为auto
,将占满整个容器的高度。
7.2.6 align-content
align-content
属性定义了多根轴线的对齐方式,如果项目只有一根轴线,该属性不起作用(也就是说项目得换行)
align-content
:flex-start
| flex-end
| center
| space-between
| space-around
| stretch
7.3 项目的属性
以下6个属性设置在项目上:
order
flex-grow
flex-shrink
flex-basis
flex
align-self
7.3.1 order
属性定义项目的排列顺序,数值越小,排列越靠前,默认为0
7.3.2 flex-grow
flex-grow
属性定义项目的放大比例,默认为0。即如果存在剩余空间,也不放大。- 如果所有项目的
flex-grow
属性都为1,那么它们将等分剩余空间。 - 如果一个项目得
flex-grow
属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
.item {
flex-grow: <number>; /** default 0 */
}
7.3.3 flex-shrink
flex-shrink
属性定义了项目得缩小比例,默认为1,即如果空间不足,该项目将缩小- 如果所有项目的
flex-shrink
属性都为1,当空间不足时,豆浆等比例缩小 - 如果一个项目的
flex-shrink
属性为0,其他项目都为1,当空间不足时,前者不缩小 - 负值对该属性无效
.item {
flex-shrink: <number>; /** default 1 */
}
7.3.4 flex-basis
flex-basis
属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto
,即项目得本来大小。它可以设为跟width
或者height
属性一样的值(比如350px),则项目将占据固定空间
.item {
flex-basis: <length> | auto; /** default auto */
}
7.3.5 flex
flex
属性是flex-grow
,flex-shrink
和flex-basis
的简写,默认值为0 1 auto
。后两个属性可选flex: 0 1 auto;
默认值flex: none;
代表的意思是等同于flex: 0 0 auto;
flex: auto;
代表的意思是flex: 1 1 auto;
flex: number;
当flex取值为一个非负数字,则该数字为flex-grow
的值,flex-shrink
的值为1,flex-basis
的值为0%
7.3.6 align-self
align-self
属性允许单个项目可以和其他项目不一样的对齐方式,可覆盖align-items
属性。默认值为auto
,表示继承父元素的align-items
属性,如果没有父元素,则等同于stretch
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
8. 移动端1px问题的多种解决方法
CSS像素为1px
高的直线,对应的物理像素是不同的,可能是2个物理像素或者3个物理像素,而设计师想要的1个物理像素的直线,而设计师要的实际1px的边框就是下面这种情况:
对于CSS而言,可以认为是border: 0.5px;
,这是多倍屏下能显示的最小单位。然而,并不是所有手机浏览器都能识别border: 0.5px
,有的系统里,0.5px
会被当成为0px
处理,那么如何1px
细线问题呢?
8.1 使用border-image实现
准备一张符合要求的边框图片,样式设置如下:
.border-bottom-1px {
border-width: 0 0 1px 0;
-webkit-border-image: url(linenew.png) 0 0 2 0 stretch;
border-image: url(linenew.png) 0 0 2 0 stretch;
}
上文是把border
设置在边框的底部,所以使用的图片是2px
高,上部的1px
颜色为透明,下部的1px
使用视觉规定的border
的颜色。
优点:可以设置单条、多条边框;
缺点:更换颜色和样式麻烦,需要更换图片;
8.2 使用background-image实现
background-image
跟border-image
的方法一样,你要先准备一张符合你要求的图片。然后将边框模拟在背景上。
.background-image-1px {
background: url(../img/line.png) repeat-x left bottom;
-webkit-background-size: 100% 1px;
background-size: 100% 1px;
}
优缺点与border-image一样;
8.3 多背景渐变实现
与background-image
方案类似,只是将图片替换为css3渐变。设置1px
的渐变背景,50%
有颜色,50%
透明。
.background-gradient-1px {
background:
linear-gradient(#000, #000 100%, transparent 100%) left / 1px 100% no-repeat,
linear-gradient(#000, #000 100%, transparent 100%) right / 1px 100% no-repeat,
linear-gradient(#000,#000 100%, transparent 100%) top / 100% 1px no-repeat,
linear-gradient(#000,#000 100%, transparent 100%) bottom / 100% 1px no-repeat
}
/* 或者 */
.background-gradient-1px{
background:
-webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #000), to(#000)) left / 1px 100% no-repeat,
-webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #000), to(#000)) right / 1px 100% no-repeat,
-webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #000), to(#000)) top / 100% 1px no-repeat,
-webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #000), to(#000)) bottom / 100% 1px no-repeat
}
优点:可以实现单条、多条边框;边框的颜色随意设置;
缺点:增加代码量,圆角没法实现,兼容性问题;
8.4 使用box-shadow模拟边框
利用对阴影处理的方式实现0.5px
的效果
.box-shadow-1px {
box-shadow: inset 0px -1px 1px -1px #c8c7cc;
}
优点:代码少,兼容性好;
缺点:边框有阴影,颜色变浅;
8.5 伪元素+transform
构建1个伪元素, border
为1px
, 再以transform
缩放到50%
把原先元素的 border
去掉,然后利用 :before
或者 :after
重做 border
,并将 transform
的 scale
缩小一半,原先的元素相对定位,新做的 border
绝对定位。
// 单条border样式设置
.scale-1px{
position: relative;
border:none;
}
.scale-1px:after{
content: '';
position: absolute;
bottom: 0;
background: #000;
width: 100%;
height: 1px;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
}
// 四条boder样式设置
.scale-1px{
position: relative;
margin-bottom: 20px;
border:none;
}
.scale-1px:after{
content: '';
position: absolute;
top: 0;
left: 0;
border: 1px solid #000;
-webkit-box-sizing: border-box;
box-sizing: border-box;
width: 200%;
height: 200%;
-webkit-transform: scale(0.5);
transform: scale(0.5);
-webkit-transform-origin: left top;
transform-origin: left top;
}
优点:可以满足所有场景,且修改灵活;
缺点:对于已使用伪类的元素(例如clearfix)要多层嵌套;
8.6 viewport + rem 实现
同时通过设置对应viewport
的rem
基准值,这种方式就可以像以前一样轻松愉快的写1px
了。
在devicePixelRatio = 2
时,输出viewport
:
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
在devicePixelRatio = 3
时,输出viewport
:
<meta name="viewport" content="initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no">
优点:所有场景都能满足,一套代码可以兼容基本所有布局;
缺点:老项目修改代价太大,只适用于新项目;
9. 图片模糊问题的多种解决方法
在不同的设备像素比下,加载不同分辨率的图片,即加载多倍图片。
9.1 media查询
使用media查询判断不同的设备像素比来显示不同精度的图片:
.avatar{
background-image: url(conardLi_1x.png);
}
@media only screen and (-webkit-min-device-pixel-ratio:2){
.avatar{
background-image: url(conardLi_2x.png);
}
}
@media only screen and (-webkit-min-device-pixel-ratio:3){
.avatar{
background-image: url(conardLi_3x.png);
}
}
9.2 image-set
.avatar {
background-image: -webkit-image-set( "conardLi_1x.png" 1x, "conardLi_2x.png" 2x);
}
9.3 srcset
使用img
标签的srcset
属性,浏览器会自动根据像素密度匹配最佳显示图片:
<img src="conardLi_1x.png" srcset=" conardLi_2x.png 2x, conardLi_3x.png 3x">
9.4 JavaScript拼接图片URL
使用window.devicePixelRatio
获取设备像素比,遍历所有图片,替换图片地址:
const dpr = window.devicePixelRatio;
const images = document.querySelectorAll('img');
images.forEach((img)=>{
img.src.replace(".", ‘@${dpr}x.’);
})
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!