初期状態で指定の幅にズームさせたスマホサイトが作れないか検討してみた
大昔にモバイルサイトの配信を中止して以来、久しぶりに、スマホ向けの軽量ページを試験導入しました。
とりあえずは、PCとスマホにそれぞれ違うページを出せる基盤を作っただけ。って事で、PC版の機能を一部取り除いたものを仮にスマホ版としています。
現時点ではスマホ版・PC版間の遷移機能は設けていないので、 必要なら Android 標準ブラウザや Chrome の「PC版サイトのリクエスト」機能を使ってもらうと、フルページにアクセスできますし、また、サイトのトップはPC・スマホ共通にしていますので、人気記事などの一覧も変わらず見れます。
ちょっとづつ色々変えていく予定ですので、よろしくおねがいします。です。
で、さて、スマホ向けサイトと言えば避けて通れないのが「Viewport」ですが、色々触っているうちに、「スマホの場合はPCサイトの本文部分の幅に最初からズーム表示させておく。なんて事ができるんじゃ?」と思って色々試してみたのでその時のメモを(自分のために)書いておきます。
※この記事は自分用メモなので、今後も更新する可能性があります。
※2013/2/28 Android版Chromeのアップデートでviewport周りが素直になったので、それに合わせて記事を修正
initial-scaleを算出するのに必要なパラメータ
Android 向けの viewport はメタタグにこんな感じで書くわけですが、
<meta name="viewport" content="target-densitydpi=medium-dpi, width=device-width, initial-scale=1, minimum-scale=0.3, maximum-scale=3.0, user-scalable=yes" />
任意の幅に合わせてズームする initial-scale を求めるには、機種ごとの初期表示領域の幅を知る必要があります。
色々試した結果、Android 4.0 版の Chrome ならこんな感じで取れそうじゃん。と。
var scWidth = screen.width; // Yields width of the Viewport. var dvPixelRatio = window.devicePixelRatio; var innerWidth = scWidth; // Yields default width of the Display area. var scaleTo = 540; var iniScale = Math.round((innerWidth/scaleTo)*10000)/10000;
※2013年2月末のChromeアップデート以前、および、2013年2月に確認した Android 4.0 標準ブラウザでは innerWidth = scWidth / dvPixelRatio; だったような。
で、こんな感じでMETAタグをセットしてやります。
var meta = document.createElement('meta'); meta.setAttribute('content', 'target-densitydpi=medium-dpi, initial-scale=' + iniScale + ', minimum-scale=0.3, maximum-scale=3.0, user-scalable=yes'); document.getElementsByTagName('head')[0].appendChild(meta);
※これらは Chrome for Android 向けのコードなので、 UserAgent 毎に調査のして書き分ける必要があるでしょう。Viewport に width は設定した方が都合が良い場合もあったような…。
OS・機種・ブラウザ・状況で異なるViewportの幅と、devicePixelRatio、innerWidth
※2013年2月末のChromeアップデートにより、以下の情報は役に立たなくなりました。screen.width がそのまま Viewport の Width になったと思います。
とりあえず、重要なのは以下の3つ。
- screen.width
→ Viewportの幅 - window.devicePixelRatio
- window.innerWidth
→ 表示領域のサイズ、ただし、レンダリング後はサイズが変わる
この内、問題なのが、innerWidth で、Android では initial-scale = 1 のプレーンな状態の数値がどうも確実には取れないような。
で、調べて見ると、こんな感じで相関関係が見いだせまして、
Viewportの幅/innerWidth/devicePixelRatio
***Chrome for Android***
某Android 4.0 480/320/1.5
某Android 4.1 800/400/2
某Android 4.2 800/600/1.33124***Safari(iOS 6.1・参考用)***
iPhone 5 320/320/2
じゃあ、initial-scale=1 の時の window.innerWidth …というか初期表示幅は、
Viewportの幅/devicePixelRatio
で求められそうじゃん。という感じ。
とりあえず Chrome for Android 限定で Viewport のメタタグを出力しようかと思ったんですが、先にも書いたとおり、Chrome の UserAgentを騙るブラウザが結構あったり、Android標準ブラウザとChromeですら、このあたりの実装が違う。って事で、混乱を招くだけかなぁ。と思い結局お蔵入りに。がっくり。
コリコリに Javascript で書きまくってやればなんとかなりそうな予感もするんですが、そこまでするのもねー。という事で。
ちなみに Android での Viewport の設定については、公式サイトが非常に良い資料と思います。
その他参考サイト