CSSでimg
要素の周囲に1pxのborderを付けた画像をChromeで表示した時、ズームで拡大していくと下図のように左右borderと画像の端との間にわずかな隙間が生じる現象に遭遇しハマったので、解決方法をここに書きます。
動作環境
macOS 10.14 (Mojave), Retinaディスプレイ(Radeon Pro 575), Chrome 79
図の上段が問題のレイアウトで、li
要素で囲んだ2つのimg要素をフロートで配置したものです。
画像出典: Lorem Picsum Images from Unsplash
HTML(要点のみ)
<div class="grid">
<ul class="img-list">
<li class="box1">
<img src="https://picsum.photos/id/1001/1222/454" alt="">
</li>
<li class="box2">
<img src="https://picsum.photos/id/326/590/454" alt="">
</li>
</ul>
</div>
CSS(要点のみ)
ul {
list-style-type: none;
}
.grid {
width: 930px;
margin: 0 auto 40px;
}
.img-list {
overflow: hidden;
}
.img-list li {
float: left;
width: 297px;
margin-right: 19px;
}
.img-list li:last-child {
margin-right: 0;
}
.img-list .box1 {
width: 613px;
}
.img-list img {
box-sizing: border-box;
width: 100%;
height: auto;
vertical-align: bottom;
border: 1px solid blue;
}
画像の枠線はimg
要素に対してborder: 1px solid blue
で付けています。このサンプルでは、Chromeで125%に拡大した時に問題の“隙間”が現れました。丸で囲った部分を拡大したのが下段の図です(デバイスピクセル比=2のモニタで確認しています)。左側がChrome、右側がFirefox1で表示したものです。Firefoxでは隙間なくぴっちりと画像の周囲に枠線が描かれるのに対して、Chromeでは1px分の隙間を入れられてしまいました。
隙間の振る舞い
今回のサンプルコードに関していえば、borderの隙間が発生する条件は倍率125%に加えていくつかあるようです。
ブラウザのウィンドウ幅が奇数ピクセルになると発生する
隙間を見分けやすくするため、画像を囲むli
要素の背景色を赤#ff0000
にしました。125%に拡大した後、ブラウザのウィンドウ幅を大きくしていくと、隙間が出たり消えたりするのがわかります(下図)。1395pxとか幅が奇数ピクセルの時に隙間が現れ、偶数ピクセルでは隙間が消えます。
包含ブロックに左右margin: autoが設定されていると発生する
サンプルのコードでは、包含ブロックdiv.grid
にmargin: 0 auto 40px
を設定しているのですが、このプロパティを消すと隙間が消えます!(下図) しかし、デスクトップ版のページレイアウトに左右marginを使わないわけにはいかないので、これは対策には使えません。
解決策
Chromeで隙間を消す方法は意外に簡単でした。CSSでたった1行、borderの太さをthin
に変えるだけ。
参考にした解法: Borders disappear in Chrome when I zoom in
img {
/* border: 1px solid blue; */
border: thin solid blue;
}
やってみましょう。下図で上側がborder: thin ...
、下側がborder: 1px ...
です。拡大率125%でウィンドウ幅を変えても、thin
に設定した方は隙間が生じないことがわかります。また、80%に縮小した時、border: 1px
の方は、左側のborderが消えてしまうのに対して、thin
の方はちゃんとborderが描かれます。
サンプルのコード: https://codepen.io/kaz_hashimoto/pen/NWqpqPV
自分の環境で確認したデスクトップ版ブラウザのうち、今回の現象が発生するのはChromeだけでした。
確認したブラウザ
- macOS: Chrome/Firefox/Safari/Opera
- Windows 10: IE11/Edge(従来版)
Chrome以外は従来どおりのborder: 1px ...
方式で大丈夫そうなので、実際の案件ではJavaScriptを使ってブラウザ判定し、UAがデスクトップ版Chromeの場合のみbody
にclassをセットして、CSSルールを分けるようにしておきました。要点だけ書くとこんな感じ。
img {
border: 1px solid blue;
}
.chrome-pc img { /* JavaScriptでbodyにclass="chrome-pc"をセットしておく */
border: thin solid blue;
}
-
Firefoxはメニューに125%の拡大がないため、このアドオンで倍率を設定: Default Zoom ↩