前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >border-image诡异细线

border-image诡异细线

作者头像
ayqy贾杰
发布2023-03-15 18:53:32
7360
发布2023-03-15 18:53:32
举报
文章被收录于专栏:黯羽轻扬黯羽轻扬

写在前面

一个诡异的border-image问题,想了很久,如下:

微信实在粘不过来,想看的话下面有图,或者查看原文,或者浏览器打开原文:

http://www.ayqy.net/blog/border-image%E8%AF%A1%E5%BC%82%E7%BB%86%E7%BA%BF/

如果手头的设备是Android,应该能看到在泡泡边框和文本之间的4条细边,如果擅长找茬,还能发现泡泡尖角下方的那条很细的横线

对应源码如下:

代码语言:javascript
复制
<div style="background-color: silver; padding: 20px;">
<div style="border: 10px solid; border-image: url(http://www.ayqy.net/temp/popup-white.png) 20 fill repeat; width: 136px;">
<div style="padding: 15px;">可爱的popup</div>
</div>
</div>

一.问题重述

应用border-image后,border boxcontent box之间有一圈透明细线,某些情况下border box外也有一圈透明细线,如上面的效果

注意:ios好像没有这个问题,但好像所有Android都有,至少Android6.0有,其它设备待测试,如果手头设备有这个问题,麻烦留言告知,谢谢

border-image相关的部分如下:

代码语言:javascript
复制
border: 10px solid;
border-image: url(http://www.ayqy.net/temp/popup-white.png) 20 fill repeat;

从2倍图上裁剪一圈20px的相框,缩到10px的border上。那么,这一圈细线是哪里来的?

P.S.为了防止bug飞走,贴图记下:

border-image 2倍图

border-image 1倍图

二.原因分析

又想起zxx那个铺地砖的例子:

这么比方吧,您从万科地产买了个99.5m*99.5m的毛坯房,地面要贴瓷砖,都是1m*1m的正方形瓷砖。如果是“平铺”,对不起,这1m边长的瓷砖不行,要处理!怎么处理法?很简单,每个瓷砖压成0.995m*0.995m的,这样就可以了,所以,平铺就是以完整的单元铺满整个区域。如果是重复,就直接把这1m*1m的瓷砖从一个角落一个一个的放置,放到头放不下了怎么办?直接把瓷砖从中间“咔”掉,于是最后会在房子的边角看到很多半截的瓷砖。

(引自CSS3 border-image详解、应用及jQuery插件 « 张鑫旭-鑫空间-鑫生活)

虽然不管怎么铺,理论上都不应该存在这4条细线,但计算总是受限于精度,比如scale引起的半像素偏移,这4条线应该与之类似,问题来自浏览器实现,或者说是计算精度损耗

如果是精度的问题,平铺(round)和重复(repeat)都存在裁剪计算,精度损耗可能会比较严重,而拉伸(stretch)没有裁剪计算,只有插值计算,理论上效果应该会好一些,下面尝试一下

三.解决方案

尝试用stretchround,具体见http://www.ayqy.net/temp/border-image-pop.html

在Android设备上发现用了stretch后没有4条细线了,暂时认为stretch是可行的解决方案

但在Chrome设备模拟会发现细线还在(Mac的Chrome也能看到细线),无论border-image-repeat的值是拉伸、平铺还是重复

在Mac Safari下,无论是正常页面还是“进入响应式设计模式”都看不到细线,而iphone5s、iphone7都看不到细线。此外,FF49存在这个问题,但没有Chrome明显,IE11完全没有这个问题。那么暂且认为这个问题是Google家特有的,因为Chrome桌面版/移动版与Android原生浏览器都有,而IOS全家好像都没有

此外,亲测发现,细线的问题与2倍图,1倍图无关,与图片尺寸无关,与fill与否无关,与屏幕ppi有关,但关系不大,具体见:

  • http://www.ayqy.net/temp/border-image.html:1倍图
  • http://www.ayqy.net/temp/border-image-pop.html:2倍图
  • http://www.ayqy.net/temp/border-image-pop-try.html:图片尺寸、旧版-webkit-outline

只有stretch时不会出现细线,其它方式都不行

P.S.甚至考虑过用子元素的outline盖掉细线,纯色不透明背景确实有效,半透明背景下很难准确设置outline的色值(尤其是设计稿是几个半透明图层叠加时),而且outline无法解决尖角下方那条细线(父元素outline: 2px solid transparent当然不行,透明了还怎么盖)

这个问题证明了另一件事情:repeatround都是从中心向两头铺的(所以才会有4条细线)

四.结论

border-image是一个强大的属性,但很遗憾,目前其真正强大的特性还没有办法使用,虽然已经好几年过去了

目前(2016-10-22)如果非要用,建议只用border-image-repeat: stretch不建议使用repeat/round,因为存在细线的问题,除非某一天Android 6.0也成为历史了

box-shadowborderborder-radiustransform可以实现大部分相框,但border-image绝对是最简单粗暴的方式,值得期待

参考资料

  • w3schools
  • MDN
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-10-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端问问 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.问题重述
  • 二.原因分析
  • 三.解决方案
  • 四.结论
    • 参考资料
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档