スマートフォンの画素数、つまり縦横のピクセル数は、1080x1920とハイビジョンに合わせてあるようです。この値は90度回転しているとはいえ、一般的なPCのディスプレイと同じです。
ウェブページが普及し始めた時期は1024x768が一般的でしたから、ピクセル数だけからいえばPC用と同じ設計でも問題なく表示できる事になります。
しかし、一つ一つの画素が小さいことが問題です。PCと同じに表示すると細かすぎて、読み取れない、指の太さから操作できないという事態になります。
もちろんこれは、htmlの問題ではありません。誕生のときから、受信側が端末の画面の大きさに合わせて文字の大きさを決め、1行の文字数を決めることになっていたからです。
しかし、スマートフォンが普及した時には、ウェブページは横幅が1024px弱の固定幅で設計することが一般的になってしまっていました。スマートフォンにもそれをそのまま表示することが期待されたわけです。
私はこの固定幅で設計することを極力避けてきましたが、それでも避けて通れない部分がありました。画像がそもそも固定された大きさを持っていることです。これを画面の大きさに合わせて拡大縮小すると、画質の劣化や表示速度の低下が起こります。
今回改めて試してみて速度的にも画質的にも性能が上がっていることに認識を新たにしました。通信速度が上がっていることも影響しているかもしれません。
ちなみに画素数の意味で「解像度」という言葉を使うこともあるようですが、解像度は72dpiなどというように単位長さあたりの画素数をいうのが本来の使い方だったと思います。小さい面積に1080x1920を表示するスマートフォンはめちゃめちゃ解像度が高いことになります。一般の人が解像度を気にするのはスマートフォンがでてきてからが妥当で、それまでは画素数を来にして欲しかったということになります。でも実際に、話題に登るのはインチでした。つまり画面の対角線の長さですね。
ただしディスプレイの物理的な構成を考えると単色の発光体を組み合わせて1つのピクセルを構成することもあるので話は厄介になります。あくまでデータのレベルで考えることにします。
Androidでは音量downボタンと電源ボタンの同時押しでスクリーンショットがとれます。この画像の大きさからスクリーンの大きさを知ることができます。「大きな画像」のシリーズで上辺に表示してある背景画像もそのためのものです。
bodyの最上部とh1の下のdivに背景として次の画像が置かれています。x方向だけ繰り返しています。
青-薄黄: 4pxごと交互
白-赤 : 8pxごと交互
黒-灰 :16pxごと交互
青赤緑 :各色32px。全体で96px
使用した環境は Android 6.0.1 上の Chrome 60.0.3112.112 ですが、縮小時の補間処理が機種により異なるので、タイトルは NEXUS 5 としています。
この機種ではスクリーンショットの横幅は1080px。画像は上部だけを合成しています。
① viewport指定なしです。画像の幅を96pxとすると「大きい画像」のタイトルの背景から、980pxの幅でレンダリングしたかったけれども画像がはみ出すのでもう少し頑張って 1440pxまでを表示しようとした。
ただし、物理的に1080pxしかないので、1080/1440=3/4 にして表示した。背景の元画像は96pxの3/4である72pxしかない。980pxも3/4の735pxになっている。
② viewport指定をした場合。画像の幅を96pxとすると「大きい画像」のタイトルの背景から、360pxの幅でレンダリングしたかったけれども画像がはみ出すのでもう少し頑張って 1440pxまでを表示しようとした。以下同様。
360pxは3/4の270pxになっている。
①②は3/4になることで、画質に多少の乱れを生じている。
③ img{max-width:100%}を追加。360pxでレンダリングしている。1080/360=3なので3倍に拡大していることになる。
背景の元画像は96pxの3倍である288pxとなっている。3/4と異なり画像に乱れがなくてもいいようなものだが、3/4にしてから4倍したような乱れが生じている。
④ これも③と同様
⑤ これも上のbodyの背景画像は③と同様だが、下のdivの背景画像は96pxの画像を3倍し288pxとして配置しているように見える。同じ背景画像で扱いが異なるのは不思議。
使用した環境は Android 7.0 上の Chrome 60.0.3112.116
傾向としてはまったく同じ。3/4にするときの誤差の出方が異なる。
使用した環境は Android 4.2.2 上の Chrome 60.0.3112.116 ですが、これにはchrome以外のブラウザもあるのでまずは、Chromeをみてみます。
この機種ではスクリーンショットの横幅は720pxです。
① viewport指定なしです。画像の幅を96pxとすると「大きい画像」のタイトルの背景から、980pxの幅でレンダリングしたかったけれども画像がはみ出すのでもう少し頑張って 1440pxまでを表示しようとした。同じです。
ただし、物理的に720pxしかないので、720/1440=1/2 にして表示した。背景の元画像は96pxの1/2である48pxしかない。980pxも1/2の490pxになっている。
② viewport指定をした場合。画像の幅を96pxとすると「大きい画像」のタイトルの背景から、360pxの幅でレンダリングしたかったけれども画像がはみ出すのでもう少し頑張って 1440pxまでを表示しようとした。同じです。
360pxは1/2の180pxになっている。
縮小が1/2なので3/4に比べて、画質の乱れは小さい。
③ img{max-width:100%}を追加。360pxでレンダリングしている。720/360=2なので2倍に拡大していることになる。
背景の元画像は96pxの2倍である192pxとなっている。一箇所欠陥があるが他は乱れはが感じられない。
④ これも③と同様
⑤ これも上のbodyの背景画像は③と同様だが、下のdivの背景画像は上記の欠陥もなく、処理が異なることを感じさせる
使用した環境は Android 4.2.2 上の Firefox 55.0.2 です。
この機種ではスクリーンショットの横幅は720pxです。
① viewport指定なしです。画像の幅を96pxとすると「大きい画像」のタイトルの背景から、980pxの幅でレンダリングしたと読み取れます。画像が大きいからといって、広げようとしない。
ただし、物理的に720pxしかないので、720/980=36/49にして表示した。背景の元画像は96pxの36/49である71pxしかない。周期的に中間色が入り調整されている。
② viewport指定をした場合。画像の幅を96pxとすると、360pxの幅でレンダリングしている。画像がはみ出しても広げようとしない。
720/360=2なので2倍に拡大していることになる。境界線はくっきりしている。
③ img{max-width:100%}を追加。360pxでレンダリングしている。②と同じ。
④ これも③と同様
⑤ 上のbodyの背景画像と、下のdivの背景画像の違いがない。viewport指定の後は同じ処理になっている様子。
使用した環境は Android 4.2.2 上の ブラウザ です。システムにデフォルトのブラウザでした。GnomeにおけるEpiphanyのようなものらしい。
この機種ではスクリーンショットの横幅は720pxです。
① viewport指定なしです。画像の幅を96pxとすると「大きい画像」のタイトルの背景から、980pxの幅でレンダリングしたかったけれども画像がはみ出すのでもう少し頑張って 2560pxまでを表示しようとした。
ただし、物理的に720pxしかないので、720/2560=9/32 にして表示した。背景の元画像は96pxの9/32である27pxしかない。これは割り切れる。980pxも9/32の276px程度になっている。
② viewport指定をした場合。画像の幅を96pxとすると、360pxの幅でレンダリングしている。画像がはみ出しても広げようとしない。
720/360=2なので2倍に拡大していることになる。境界線はくっきりしている。
③ img{max-width:100%}を追加。360pxでレンダリングしている。②と同じ。
④ これも③と同様
⑤ 上のbodyの背景画像と、下のdivの背景画像の違いがない。viewport指定の後は同じ処理になっている様子。
より広い範囲を表示しようとする意欲は違いが見られるが、980pxが共通の目安になっている。
viewport指定をした場合は、360pxであるかのようにレンダリングしようとする。preやimgがその範囲に入らない時の対応はソフトウェアによるが、適切なスクロールや縮小の指示をすることで360pxに収めることができる。