CSS设置1px变粗的原因:
为什么移动端css里面写了1px, 实际看起来比1px粗. 其实原因很好理解:这两个“px”的含义是不一样的. 移动端html的header总会加上一句:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
这句话定义了本页面的viewport的宽度为设备宽度,初始缩放值和最大缩放值都为1,并禁止了用户缩放. viewport通俗的讲是浏览器上可用来显示页面的区域, 这个区域是可能比屏幕大的。css中的像素只是一个抽象的单位,在不同的设备或不同的环境中,css中的1px所代表的设备物理像素是不同的。
viewport详细解释推荐:移动前端开发之viewport的深入理解
实现0.5px的边框或线的方法:
方法一: 定位+缩放
利用的是 transform 缩放功能,将 1px 缩放一半,同时利用定位,将伪元素覆盖整个 div 元素,从而达到伪元素与本身元素的合并效果。
.button {
position: relative;
}
.button::before { content: ""; position: absolute; top: 0; left: 0; min-width: 200%; height: 200%; border: 1px solid $color-black54; transform-origin: 0 0; transform: scale(.5, .5); }
支持的浏览器:Firefox: ✅ Safari: ✅ Chrome: ✅
需要注意<input type="button">是没有:before, :after伪元素的
方法二: box-shadow
利用的是 box-shadow
的扩散半径可以设置为 0.5px 原理
box-shadow: 0px 0px 0px 0.5px #f00;
支持的浏览器: Firefox: ✅ Safari: ❌ Chrome: ✅ Firefox: ✅ Safari: ✅
方法三: 线性渐变 linear-gradient
.box {
height: 1px;
background: linear-gradient(#f00 50%, transparent 50%);
}
方法四: SVG
.HalfPixelLine{ background: repeat-x top left url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='1' height='1'><rect fill='red' x='0' y='0' width='1' height='0.5'/></svg>"); height: 1px; width: 100%; }
方法五: 直接使用border属性
border: 0.5px solid #f00;
支持的浏览器: Firefox: ✅ Safari: ✅ Chrome: ❌
方法六: flexible.js
这是淘宝移动端采取的方案, github的地址:https://github.com/amfe/lib-flexible. 前面已经说过1px变粗的原因就在于一刀切的设置viewport宽度, 如果能把viewport宽度设置为实际的设备物理宽度, css里的1px不就等于实际1px长了么. flexible.js就是这样干的.
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
devicePixelRatio=2时输出meta如下, 这样viewport与ideal viewport的比是0.5, 也就与设备物理像素一致
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
缺点:不适用安卓, flexible内部做了检测 非iOS机型还是采用传统的scale=1.0, 原因在于安卓手机不一定有devicePixelRatio属性, 就算有也不一定能响应scale小于1的viewport缩放设置, 例如我的手机设置了scale=0.33333333, 显示的结果也与scale=1无异。