CSS3实现半像素边框

一.思路

普通的1px黑色实线边框:

border: 1px solid #000;

半像素边框当然不是简单地把1px改为0.5px(没测试过,可能会被解析成1或者0),border-width的值只能是自然数

类似的,outline, box-shadow等等也没有办法画出0.5px的细线

常规思路是不可行的,我们可以用伪元素 + 缩放巧妙地实现,具体步骤如下:

  1. 设置目标元素作为定位参照

    .thinner-border {
        position: relative; /* 只要不是默认值static即可 */
    }
    
  2. 给目标元素添加一个伪元素before或者after,并设置绝对定位

    .thinner-border:before {
        content: '';
        position: absolute;
    }
    
  3. 给伪元素添上1px的边框

    border: 1px solid red;
    
  4. 设置伪元素的宽高为目标元素的2倍

    width: 200%;
    height: 200%;
    
  5. 缩小0.5倍(变回目标元素的大小)

    transform-origin: 0 0;
    transform: scale(0.5, 0.5);
    
  6. 把border包进来

    box-sizing: border-box;
    

简言之就是先放大再缩回来,border-box是关键,否则边框不会一起缩放

二.具体实现

上面已经分步骤写得很清楚了,拼在一起就是完整实现:

.thinner-border {
    position: relative;
}

.thinner-border:before {
    content: '';
    position: absolute;
    width: 200%;
    height: 200%;
    border: 1px solid #000;
    -webkit-transform-origin: 0 0;
    -moz-transform-origin: 0 0;
    -ms-transform-origin: 0 0;
    -o-transform-origin: 0 0;
    transform-origin: 0 0;
    -webkit-transform: scale(0.5, 0.5);
    -ms-transform: scale(0.5, 0.5);
    -o-transform: scale(0.5, 0.5);
    transform: scale(0.5, 0.5);
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}

功能是给class值指定了thinner-border的block和inline-block元素添上半像素的边框,因为inline元素的width和height有一些限制,伪元素获取到的200%要比实际值小,边框的宽高也会比期望的小

三.Demo

1像素边框,block

半像素边框,block

1像素边框,inline 半像素边框,inline-block 半像素边框,inline,边框太窄
1/4像素边框

边框效果用移动浏览器看更明显,变化的是线宽而不是颜色

注意:虽然理论上边框可以任意细(1/n px),但由于存在精度的问题(精度影响边框的宽高),所以半像素边框是最有实用意义的,虽然也存在问题:如果宽高是奇数则边框位置会偏移0.5px,实际应用中尚可接受

CSS3实现半像素边框》上有6条评论

  1. lk

    确实很好用!不过如果要绑定click事件的话,就点不到,因为伪元素在上一层,不知道有没有解决方法。

    回复
    1. ayqy 文章作者

      理论上是点得到的,因为伪元素的z-index并没有比元素自身的大。如果有特殊需要,伪元素确实盖在元素上面的话,用pointer-events: none可以让点击等行为穿透到下层,目前FireFox浏览器,Chrome都支持。Opera以及IE不支持。

      (对文中的Demo测试,onclick不受影响,理论上也不应该影响)

      回复
  2. jeff

    我用过这个方法后在手机上显示右边框是1px,其他都好着是什么原因啊

    回复
  3. tomoyii

    一直看淘宝和京东有小于1px的细线,教程哪里都找不到,现在终于有教程了,太感谢了!

    回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*

code