CSSのbox-sizingがサイズ指定した画像がぼやける原因です。
cssのbox-sizingでborder-boxが設定されているとテキスト系の画像がぼやける場合がある。
content-boxの場合、要素のpaddingやborderはwidth・heightに含まれないので、画像はサイズ通り映る。
border-boxの場合、要素のpaddingやborderはwidth・heightに含まれるので、その分画像サイズが小さくなりぼやける。
サイズ通り指定したイメージ画像がぼやける事ありませんか?
WEBページの画像がぼやける
皆さんはWEBページの制作中にこんな経験はありませんか?
img画像のサイズ通りにwidthとheightを指定しているのに、なぜかWEBページ上で画像がぼやけて見える状態です。
私も一時期この事に悩まされていました。
Photoshopなどで画像を作成し、そのサイズ通りにimgタグを設置しています。
テキストの映った画像では顕著にわかる
当然Photoshop上では鮮明な画像の状態なのですが、なぜかWEBサイト上ではちょっとぼやけた様な感じになるのですね。
少しぼやけたテキスト系画像
写真画像だとわかりにくいのですが、上記の様な文字やテキストなどが映った画像だと若干ぼやけているのがわかります。
本記事ではこの症状の原因と解決方法をご紹介します。
はっきりしたテキスト系画像
レスポンシブデザインにおける画像サイズ指定
少し前まで、imgタグにサイズ指定をしなくてもそれほど問題にはならない時期がありました。
widthやheightを記述していなくても、CSSで対象となるimgの幅を100%にすると周りの枠一杯に広がってくれます。
横幅サイズに応じて高さも自動で決定されるので、自然と画像が収まっていた訳ですね。
WEBページの表示速度が重視される
ところが最近になり、HTMLソース上にwidthやheightをきちんと指定する必要性が出てきました。
指定しておく事で、画像のレンダリング位置を事前確保できるのが理由です。CSSにサイズ指定しても事前確保はできません。
事前確保により、画像読み込み(遅延読み込み)によるレイアウトのズレ(SEO上でのCLS要素)を抑える事ができる訳です。
Googleが重要視している以上無視する訳にはいきません。
テキストが映る画像だとぼやけやすい
そもそも写真はともかく、テキスト等シンプルな造形が入る画像は実寸サイズを離れると荒れやすくなります。
枠に対して100%で広がってくれるからと言って、サイズがマッチしていない画像を作ると画像上のテキストが非常に見にくくなるのです。
特にブログなどで操作説明などの解説画像を入れる場合は、ぼやけが顕著に現れますよね。
CSSスタイルのbox-sizingが原因
CSSのスタイルの「box-sizing」プロパティをご存じですよね。
原因はズバリ!このbox-sizingの指定が影響しているのです。
既存テンプレートに設定済みの場合あり
完全に一からCSSを自作しているのであれば、box-sizingを自身で設定しますから原因に気づく事でしょう。
しかしテンプレートCSSなど最初から出来上がっているものを利用する場合は注意が必要です。
さりげなくbox-sizingの指定がされている場合があるからです。
テンプレートbootstrap.css内記述
* { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }
box-sizingプロパティとは
box-sizingプロパティとは「各要素のサイズにどこまで含めるか」を指定するものです。
主に指定は2つあります。
プロパティの種類
box-sizing: content-box;
box-sizing: border-box;
上記はそれぞれでレイアウトが変わります。
content-boxに設定した場合、要素の幅は単純にコンテンツの幅と高さになります。
それに対しborder-boxを設定した場合、要素の幅はborderやpaddingサイズも込みになるのです。
両者間の違い
content-box; を指定したサンプル1
width: 500px;×height: 150px;
border-box; を指定したサンプル2
width: 500px;×height: 150px;
両方とも、widthは500px、heightは150pxでCSSに設定しています。
上のサンプル1はバイオレット色部分だけでwidthが500、heightが150あるのに対し、下のサンプル2はpaddingと border部分も込みで500と150のサイズです。
丁度、上の実寸サイズ(バイオレット色部分)が、下のborder込みの総合サイズと同じなのがわかります。
※スマホ版では枠外へのはみ出しを防ぐため、サンプル1もborder-boxにしています。
box-sizingによるレイアウトの変化
ではもう少し詳しく解説していきましょう。
まず800pxの枠に対し、800px×400pxのサイズで画像を作ったとします。
.img-box{ width: 800px; }
<div class="img-box"> <img width="800" height="400" src="../images/image.png" alt=""> </div>
imgタグに直接width・heightの指定をしています。
※これはCSSにサイズを指定した場合も同じ状態になります。
content-boxを指定した場合
この画像にcontent-boxを指定したとします。
.img-box img{ box-sizing: content-box; }
この場合、外枠のimg-boxの幅800pxに対しimgの幅が800pxですから、画像は問題なく鮮明に表示されます。
画像の周囲に10pxの枠線を付ける
ではこの時、画像に10pxの枠線を付けるとどうなるでしょう。
当然imgタグへのサイズ指定は変えずにです。
.img-box img{ box-sizing: content-box; border: solid 10px #cc0000; }
これにより画像周囲を10pxの枠が覆います。
枠がつこうがcontent-boxが設定されている限り、幅と高さは画像サイズ通りです。
これにより画像のサイズは上下左右それぞれ20pxずつ大きくなり、820px×420pxとなる訳ですね。
となると画像の横幅が枠をはみ出してしまう事になります。
border-boxを指定した場合
では先ほどのCSS設定でcontent-boxではなくborder-boxを指定した場合はどうなるのでしょうか。
.img-box img{ box-sizing: border-box; border: solid 1px #999999; }
この場合、img画像の800px幅は「border枠込み」のサイズになります。
ですのでソース上はwidth="800"としていても実寸は「780px」になり、その分だけ画像が縮小されるのです。
これがまさに先ほどから説明している画像がぼやける原因です。
800px幅を超えていませんから、はみ出る事なく枠内に収まります。
border-boxの場合、枠線を入れると実寸より小さくなる
私の場合はまさにこの状態で、画像の周りに1pxの枠を敷いていました。
これがサイズ通りに画像を設置しているにも関わらず、画像がぼやける原因でしたね。
800pxで表示しているつもりが実際は798pxだった訳です。
文字テキストを画像として表示させていた場合に文字が見にくく感じていました。
paddingが入っても同じ
content-boxはborderだけでなく、paddingの余白も含みません。
ですのでimgにpadding領域が設定されている場合も、その分だけ実寸サイズを小さくして調整しようとします。
それだけ画像が小さくなってしまうのですね。
外枠に限らずサイズは縮小される
border-boxに設定した要素は外枠をはみ出す・はみ出さないに限らず、実寸サイズが小さくなります。
単に100px×100pxの画像を1pxの枠線で囲って、周りに十分な余裕をもって掲載していても、border-boxにしていると画像は99px×99pxに縮小される訳です。
その画像にさらに10pxのpaddingを付けていれば、89px×89pxになってしまうのです。
box-sizingの解決方法
となると解決方法としては、対象となる画像に対して「box-sizing: content-box;」を適用する事になりますね。
そうすれば800px幅の画像であれば枠線を引いても画像自体は800pxのままです。
指定サイズ通りのサイズで画像が表示されますのでぼやける事は無いはずです。
border-boxのメリット
しかしPCスマホ一体型レスポンシブデザインが主流の今、安易にcontent-boxを使えば良いと考えるのはナンセンスです。
border-boxを全く使わないままでは通用しません。
画像に枠線を敷いてcontent-boxを使った場合、スマホでは枠をはみ出るので左右にWEBページ画面がずれる現象が起きる場合があります。
その点border-boxであれば外枠をはみ出さないので、スマホレイアウトでは有利な訳です。
border-boxなら画像を100%幅に設定しても問題がない
そもそもborder-boxはレスポンシブデザインのためにあるといっても良い要素です。
特にスマホ版で100%幅にして、できるだけ大きく画像を表示させたい訳ですからね。
imgにpaddingやborderが入っていても、それ込みで枠内100%幅になってくれます。
ただしその分画像の実質的なサイズは小さくなります。
スマホ版CSSのみにborder-boxを設定する
画像などの要素にPC版でもborder-boxを指定していると、paddingやborderの分だけ常にサイズが縮小されます。
それが外枠サイズとは無関係の100px×100pxの小さな画像であってもです。
ですので基本的にPCブラウザ表示の時は、サイズ指定に気を付けていればcontent-boxで良いと思います。
そしてスマホ版CSSで画像などを100%幅で見せたい時のみに、border-boxを適用するのがベストなのではないでしょうか。
いろいろ試してみました
paddingやborderを要素から消す
常にborder-boxをベースとして維持する場合、対象要素は常に小さくなります。
ならばテキスト系画像など縮小されたくない要素のみ、paddingやborderを消すのも一つの方法ですね。
要素を取り囲む外枠に装飾を加え、要素自体は装飾せずにborder-boxにしておくのも手です。
画像を一回り小さく作ってもダメ
1pxの枠線を付けると800pxが798pxになるのなら、前もって798pxで作っておけば良いのではと思うでしょうが、それはダメです。
常にborder込みのサイズになるので、width="798"としても次は実寸が796pxとなりさらに小さくなってしまいます。
当たり前の事ですが念のため。
画像を一回り大きく指定すると?
では実寸を800px×400pxサイズで画像を作って、width・height指定を2pxずつ大きくするのはどうでしょうか。
枠線は1pxと仮定 <img width="802" height="402" src="../images/image.png" alt="">
これで理論上はborder分を差し引くと、800px×400pxになるはずですよね。
実際にやってみましたが、サイズ数値(奇数や偶数)によってはやはりぼやけるようですね。
管理者ツールで確認した場合
ChromeなどのブラウザでF12を押すと管理者ツールが表示されます。
ここで実際の画像サイズがそのように測定されるのかを確認してみましょう。
本サンプルでのレイアウト枠サイズは横幅が705pxであり、705px×619pxのテキスト表示の画像を設置しています。
それに対し1pxの赤い枠線で囲んでいます。
content-boxの場合
box-sizingがcontent-boxの場合のそれぞれの数値をみてみましょう。
要素タブのHTMLソース上のポップアップでは705px×619pxとサイズ通りです。
それに対しページ上のツールチップでは、枠線込みで707px×621pxとなっています。
この場合枠をはみ出してはいますが、画像はサイズ通り鮮明に映っています。
border-boxの場合
ではbox-sizingがborder-boxの場合を見ていきます。
要素タブのHTMLソース上のポップアップでは、703px×617pxと1px回り小さくなっています。
それに対しページ上のツールチップでは、枠線込みで705px×619pxとなっているのがわかりますね。
この場合画像の実寸は、上下左右に1pxずつ縮小された状態「703px×617px」になるのです。
両者のぼやけの差は歴然です。
まとめ
以上box-sizingによる画像がぼやける問題と解決方法を紹介しました。
以下にポイントをまとめてみました。
box-sizingのポイント
・cssのbox-sizingプロパティには、content-boxとborder-boxとがある。
・content-boxの場合、要素のpaddingやborderは、要素のwidth・heightに含まれない
・border-boxの場合、要素のpaddingやborderは、要素のwidth・heightに含まれる
content-box(要素にpaddingやborderが設定されている場合)
・画像の場合は作成時のサイズ通りなので、鮮明に映る
・サイズによっては外枠をはみ出す場合がある
・スマホ版CSSで100%幅指定していても画面外にはみ出る場合あり
border-box(要素にpaddingやborderが設定されている場合)
・画像の場合は作成時のサイズより常に小さくなるため、ぼやける
・指定サイズを守るため、外枠をはみ出したりしない
・スマホ版CSSで100%幅指定していれば画面外にはみ出ない