开局一张图
理解这张图,需要先了解以下几个概念
设备像素
: 类似于密度,即每英寸的像素点数量,跟设备有关设备独立像素
: 我们可以理解为css
像素,跟设备无关设备像素比
: 就是devicePixelRatio
,简称drp
,可以通过window.devicePixelRatio
获取到当前设备的dpr
,我们常说的x 倍屏
中的x
就是这个dpr
其中设备像素比
= 设备像素
/ 设备独立像素
有做过移动端的同学基本是都了解过我们的设计稿一般都是750 * 1334
,750 * 1334
就是以iPhone 6/7/8
的尺寸为设计基准,就是上面说到的设备像素
一般在做移动端开发的时候,在浏览器上可以切换成移动设备模式,这个时候可以看到以下信息
这里我们可以看到 设备像素比devicePixelRatio
= 设备像素
/ 设备独立像素
1px问题
做过前端的开发的,应该基本都有关这样的经历设计稿上的1px渲染之后变粗了
, 也都知道写样式时要根据设计稿上的值除以2
,然而除以2
并不能比较完美的解决问题
以iPhone 6(dpr为 2)
为例,这是分别设置了 border-bottom: 1px solid #f00;
和 border-bottom: 0.5px solid #f00;
的渲染效果,可以看到这个1px
比我们想象中的要粗一些
,就是因为设备dpr
的原因,才导致出现这样的效果
如何解决 1px 问题
一、媒体查询
@mixin border1px($color: #ddd, $direction: 'top') {
@if $direction == 'all' {
border: 1PX solid $color;
} @else {
border-#{$direction}: 1PX solid $color;
}
@media (-webkit-min-device-pixel-ratio: 2) {
@if $direction == 'all' {
border: 0.5PX solid $color;
} @else {
border-#{$direction}: 0.5PX solid $color;
}
}
@media (-webkit-min-device-pixel-ratio: 3) {
@if $direction == 'all' {
border: 0.333333PXPX solid $color;
} @else {
border-#{$direction}: 0.333333PXPX solid $color;
}
}
}
还是刚才那两条线,还是那个iPhone 6P
,使用了媒体查询之后的渲染
然而这种方式虽然比较简单
,但是放在以前的那个时候并不可行,因为0.5px
并不是任何设备上都支持的,比如IOS8以下、以及一些安卓系统都不支持
,但是对于今天的浏览器来说,基本上是都支持的,目前我们项目中用到的也是这样方案
二、transform + 伪元素
.border-bot-1 {
width: 100%;
height: 100px;
overflow: hidden;
position: relative;
}
@media (-webkit-min-device-pixel-ratio: 2) {
.border-bot-1::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
border-top: 1px solid red;
transform: scaleY(0.5);
transform-origin: left top;
}
}
@media (-webkit-min-device-pixel-ratio: 3) {
.border-bot-1::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
border-top: 1px solid red;
transform: scaleY(0.333333);
transform-origin: left top;
}
}
这种方案可以支持圆角
,但是对已经使用伪元素
的dom
需要增加额外的层级嵌套,而且transform
会把整个盒子缩放,为了不影响其他的内容,需要单独为了边框增加一层 dom
另外可以用transform
来解决12px
以下的字体, 一般我们开发的时候,会遇到一些字体在12px
以下的情况,但是在浏览器,对字体的渲染最小是12px
,当我们需要去设置一个10px
的字体时,像这样font-size: 12px;transform: scale(0.8333333);
就可以解决了
另外,还有background-image
svg
等方案,来解决1px
问题
三、flexible
在讨论这种方案之前,先来了解以下基本概念:
viewport
:viewport
是严格等于浏览器的窗口,在桌面浏览器中,viewport
就是浏览器窗口的宽度高度,但在移动端设备上就有点复杂,移动端的viewport
太窄,为了能更好为css
布局,所以提供了两个viewport
:-
虚拟的viewportvisualviewport
:在不对屏幕进行缩放的前提下,相当于你的手机的可视区域布局的viewportlayoutviewport
&