配合pointer-events实现1px边框
从乔帮主发布Retina设备开始兴起后,移动端的h5就多了一个烦人的1px。然后设计师们对1px格外青睐,设计稿(750尺寸)中各种1px分割线,1px边框。
对于下图中一系列的的1px边框通常的实现方式

在最外层A进行transform:scale(0.5)
给每一个B元素加上transform:scale(0.5)
以上两种方式由于transform:scale(0.5)的影响,在写内部元素的大小时,都需要放大两倍,虽然只是*2,但是算起来还是略烦的。
下面介绍另外一种,pointer-events配合transform:scale(0.5)来实现1px边框的方式:
html:
css:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| .b-div { position: relative 按照正常的布局计算方式来写 */ } .b-div::before { content: ''; position: absolute; display: block; left: 0; top: 0; z-index: 10; pointer-events: none; box-sizing: border-box; height: 200%; width: 200%; overflow: hidden; border: 1px solid #fc9153; transform: scale(0.5); transform-origin: left top }
|
上面通过伪类before来绘制1px边框。 在before上,将pointer-events的属性设置为none,边框元素虽然在b-div上层,但是不会有事件的响应,所有的事件会透到b-div上。如此一来,before伪类就仅仅是能”看到“而已
配合stylus的话,可以将1px边框的实现抽离出来,写成一个单独的mixin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| border-1px($bordercolor, $bordertopleftradius = 0px, $bordertoprightradius = 0px, $borderbottomleftradius = 0px, $borderbottomrightradius = 0px) &::before content: " " position: absolute display: block left: 0 top: 0 z-index: 10 pointer-events: none box-sizing: border-box height: 200% width: 200% overflow: hidden border: 1px solid #fc9153 border-top-left-radius: $bordertopleftradius border-top-right-radius: $bordertoprightradius border-bottom-left-radius: $borderbottomleftradius border-bottom-right-radius: $borderbottomrightradius transform: scale(0.5); transform-origin: left top
|
剩下的就是在有1px边框的元素上,设置position,然后css中加入border-1px(),内部元素计算大小时不需要在*2了。
1 2 3
| .b-div position: relative border-1px(#fc9153)
|
兼容性
pointer-event的兼容性还是比较好的, 具体参看caniuse
该方法的弊端
采用rem布局时,计算出的div(下面称为b-div)和边框的div(下面称为1px-div)会出现小数,如果b-div设置了overflow:hidden,则在部分安卓机器下会出现右边或者下边边框线消失的问题。
目前找到的解决方法是b-div不要设置overflow:hidden。
由于1px-div和b-div是两个独立的div,所以如果元素带圆角的话,需要同时设置1px-div和b-div的圆角,并且要一致。