はじめに
不可解な border-image の問題で、ずっと考えていました。以下の通りです:
もし手元の端末が Android の場合、吹き出しの枠とテキストの間の4 本の細い線が見えるはずです。もし細かな違いを見つけるのが得意なら、吹き出しの尖った角の下にある非常に細い横線にも気づくでしょう
対応するソースコードは以下の通りです:
<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;">かわいい吹き出し</div>
</div>
</div>
一.問題の再述
border-image を適用すると、border box と content box の間に透明な細線が一圈現れます。場合によっては border box の外側にも透明な細線が一圈現れます。上記の効果のようです
注意:iOS ではこの問題はないようですが、すべての Android にあるようです。少なくとも Android 6.0 にはあります。他の端末はテスト待ちです。もし手元の端末にこの問題があれば、コメントで知らせてください。ありがとうございます
border-image に関連する部分は以下の通りです:
border: 10px solid;
border-image: url(http://www.ayqy.net/temp/popup-white.png) 20 fill repeat;
2 倍図から 20px の枠を一圈切り抜き、10px の border に縮小します。では、この一圈の細線はどこから来たのでしょうか?
P.S. バグが逃げないように、スクリーンショットを記録します:
[caption id="attachment_1194" align="alignnone" width="169"]
border-image 2 倍図[/caption]
[caption id="attachment_1195" align="alignnone" width="169"]
border-image 1 倍図[/caption]
二.原因分析
また zxx のタイル敷きの例を思い出しました:
こんな比方吧、您从万科地产买了个 99.5m*99.5m 的毛坯房,地面要贴瓷砖,都是 1m*1m 的正方形瓷砖。如果是“平铺”,对不起,这 1m 边长的瓷砖不行,要处理!怎么处理法?很简单,每个瓷砖压成 0.995m*0.995m 的,这样就可以了,所以,平铺就是以完整的单元铺满整个区域。如果是重复,就直接把这 1m*1m 的瓷砖从一个角落一个一个的放置,放到头放不下了怎么办?直接把瓷砖从中间“咔”掉,于是最后会在房子的边角看到很多半截的瓷砖。
(出典 CSS3 border-image 详解、应用及 jQuery 插件?张鑫旭 - 鑫空间 - 鑫生活)
どのように敷いても、理論上はこの 4 本の細線が存在するはずはありません。しかし、計算は常に精度に制限されます。例えば scale による半ピクセルのずれなどです。この 4 本の線はそれと類似しているはずです。問題はブラウザの実装、あるいは計算精度の損失からです
精度の問題であれば、タイル状(round)と繰り返し(repeat)にはどちらも切り抜き計算が存在し、精度の損失が深刻になる可能性があります。一方、伸縮(stretch)には切り抜き計算がなく、補間計算のみなので、理論上効果はもう少し良くなるはずです。以下で試してみます
三.解決策
stretch と round を試しました。詳細はhttp://www.ayqy.net/temp/border-image-pop.htmlをご覧ください
Android 端末で stretch を使用すると 4 本の細線が消えることを発見しました。一時的に stretch が実行可能な解決策だと考えています
しかし、Chrome デバイスエミュレーションでは細線が残っていることがわかります(Mac の Chrome でも細線が見えます)。border-image-repeat の値が伸縮、タイル状、繰り返しのいずれであってもです
Mac Safari では、通常のページでも「レスポンシブデザインモード」に入っても細線は見えません。iPhone 5s、iPhone 7 でも細線は見えません。さらに、FF49 にはこの問題がありますが、Chrome ほど顕著ではありません。IE11 は全くこの問題がありません。では、一時的にこの問題は Google 系特有だと考えられます。Chrome デスクトップ版/モバイル版と Android 原生ブラウザの両方にあり、iOS 製品にはないようです
さらに、実際にテストしたところ、細線の問題は 2 倍図、1 倍図とは無関係で、画像サイズとも無関係で、fill の有無とも無関係で、画面 PPI と関係がありますが、関係は大きくありません。詳細は以下をご覧ください:
-
http://www.ayqy.net/temp/border-image-pop-try.html:画像サイズ、旧版
-webkit-、outline
stretch の時のみ細線が現れず、他の方式ではダメです
P.S. 子要素の outline で細線を隠すことも考えました。単色の不透明な背景なら確かに効果がありますが、半透明の背景では outline の色値を正確に設定するのが難しいです(特にデザインカンプがいくつかの半透明レイヤーが重なっている場合)。また、outline では尖った角の下の細線を解決できません(親要素 outline: 2px solid transparent はもちろんダメです。透明なのにどうやって隠せますか)
この問題は別のことも証明しています:repeat と round はどちらも中心から両端に敷きます(だから 4 本の細線があるのです)
四.結論
border-image は強力なプロパティですが、残念ながら、現時点でその真に強力な機能はまだ使用できません。数年が経過しましたが。
現在(2016-10-22)、もし使う必要があるなら、border-image-repeat: stretch のみを使用することをお勧めします。repeat/round の使用はお勧めしません。細線の問題があるためです。ある日 Android 6.0 も歴史になるまでは。
box-shadow、border、border-radius、transform で大部分の枠を実装できますが、border-image が絶対に最も単純で力強い方法です。期待する価値があります。
コメントはまだありません