Android向けページで解像度(画素数)固定するにはviewportにdensitydpiを指定するのがいいみたい

スマホ向けのWebページをつくる際、ページの想定する解像度や拡大・縮小の可否を指定するために、metaタグでviewportを指定するのが一般的。たとえばこんな感じ。

<meta name="viewport" content="width=device-width" />

上記の場合、デバイスの解像度にあわせてコンテンツを配置するため、端末ごとに横幅のピクセル数が異なる。そのため、端末によってはうまくレイアウトされない場合がでてくる。


そこで、widthの設定を変えて、どの端末でも横幅640ピクセル相当になるように拡大・縮小表示することができる。

<meta name="viewport" content="width=640" />

iOSバイスの場合上記の設定でうまくいく(らしい)が、Androidの標準ブラウザはwidthにピクセル値を指定した際の動作があやしく、文字列の自動改行の位置がおかしくなったりする。


Androidの場合、viewportにtarget-densitydpiというパラメータが用意されているため、これを利用してサイズ調整するのが良いようだ。

これは、コンテンツを表示する際に、1インチあたり何ドット(ピクセル)かを指定するパラメータで、デフォルト値は160dpiになっている。


横幅800ピクセルの解像度の端末に、640ピクセルで表示されることを想定したコンテンツを表示しようとした場合、160 * 640 / 800 = 128 (dpi)になる。
これをviewportで記述すると以下のようになる。

<meta name="viewport" content="width=device-width,target-densitydpi=128" />

ただ、端末の解像度によりviewportの指定を変化させるには、ページロード時にJavaScriptにより動的にdensitydpiの値を変化させる必要がある。


そこで、ページの先頭で以下のようなスクリプトを実行し、viewportの指定を書き換えてみた。
(一部jQueryを使用している。ただしmetaタグを追加するところはなぜかjQueryではできなかったため、DOMを直接操作している)

var width = 640; //指定したい解像度
var defaultDpi = 160; //デフォルト値


//viewportを変更するため、元々あったviewportを削除
$('meta[name=viewport]').remove();


// jQuery でmetaタグを操作できないのでDOMを直接変更
var densityDpi = (defaultDpi * width / screen.width) | 0;
var meta = document.createElement('meta');
meta.setAttribute('name', 'viewport');
meta.setAttribute('content', 'width=device-width, target-densitydpi=' + densityDpi);
document.getElementsByTagName('head')[0].appendChild(meta);

これで端末の解像度が変わっても、横幅は同一のピクセル値だとしてページをレイアウトすることができるようだ。


レスポンシブwebデザインの潮流には反するが、多少の崩れも許容できないような場合は役にたつかと。