在了解为什么会出现1px的问题之前先讲解俩个概念:
物理像素:物理像素是每个手机在出场的时候,每个手机的设备像素,也叫硬件像素。
逻辑像素:逻辑像素是css记录的像素。
为什么会出现1px问题(主要是iphone中出现)
其实出现1px的原因还是在于,UI设计师要求的1px是物理像素,而我们开发写的css是逻辑像素,他们是不一样的,存在一个换算比例,通常JavaScript可以通过window.devicePixelRatio来获取,在iPhone上出现边框原因就是因为devicePixelRatio=2,而border-width=1,边框被放大了俩倍,导致出现边框变宽。
那么解决的方案有哪些呢?
/* 2倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 2.0) {
.border-bottom::after {
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}
}
/* 3倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 3.0) {
.border-bottom::after {
-webkit-transform: scaleY(0.33);
transform: scaleY(0.33);
}
}
div {
-webkit-box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.5);
}
box-shadow: h-shadow v-shadow [blur] [spread] [color] [inset]
将阴影尺寸设置为负数,设置成-1px 是为了让阴影尺寸稍小于div元素尺寸,这样左右两边的阴影就不会暴露出来,实现只有底部一边有阴影的效果。从而实现分割线效果(单边边框)。
整体思路:是在viewport设置缩放,通过js去动态修改viewport的值。
在页面初始化的时候,设置viewport:
通过js来动态实现对viewport的修改:
var viewport = document.querySelector("meta[name=viewport]")
if (window.devicePixelRatio == 1) {
viewport.setAttribute('content', 'width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no')
}
if (window.devicePixelRatio == 2) {
viewport.setAttribute('content', 'width=device-width, initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no')
}
if (window.devicePixelRatio == 3) {
viewport.setAttribute('content', 'width=device-width, initial-scale=0.333333333, maximum-scale=0.333333333, minimum-scale=0.333333333, user-scalable=no')
}
var docEl = document.documentElement;
var fontsize = 10 * (docEl.clientWidth / 320) + 'px';
docEl.style.fontSize = fontsize;
原理:将原本1个物理像素的边框大小利用线性渐变分割成几个部分(百分比控制),实现小于1像素效果。
.border {
background-image:linear-gradient(180deg, red, red 50%, transparent 50%),
linear-gradient(270deg, red, red 50%, transparent 50%),
linear-gradient(0deg, red, red 50%, transparent 50%),
linear-gradient(90deg, red, red 50%, transparent 50%);
background-size: 100% 1px,1px 100% ,100% 1px, 1px 100%;
background-repeat: no-repeat;
background-position: top, right top, bottom, left top;
padding: 10px;
}
linear-gradient
:指定线性渐变,接受大于等于3个参数,第一个为渐变旋转角度,第二个开始为渐变的颜色和到哪个位置(百分比)全部变为该颜色,该例子中,第一句就是,渐变方向旋转180度,即从上往下(默认为0度从下往上),从红色开始渐变,到50%的位置还是红色,再渐变为继承父元素颜色。
.border-image-1px {
border-width: 1px 0px;
-webkit-border-image: url("border.png") 2 0 stretch;
border-image: url("border.png") 2 0 stretch;
}
border-width
:指定边框的宽度,可以设定四个值,分别为上右下左border-width: top right bottom left。border-image
:该例意为:距离图片上方2px(属性值上没有单位)裁剪边框图片作为上边框,下方2px裁剪作为下边框。距离左右0像素裁剪图片即没有边框,以拉伸方式展示。div {
height:1px;
background:#000;
-webkit-transform: scaleY(0.5);
-webkit-transform-origin:0 0;
overflow: hidden;
}
div::after{
content:'';width:100%;
border-bottom:1px solid #000;
transform: scaleY(0.5);
}
.div::after {
content: '';
width: 200%;
height: 200%;
position: absolute;
top: 0;
left: 0;
border: 1px solid #bfbfbf;
border-radius: 4px;
-webkit-transform: scale(0.5,0.5);
transform: scale(0.5,0.5);
-webkit-transform-origin: top left;
}