スマホ・タブレットで縦横の表示切り替えに応じてレイアウトを変えつつ画面ぴったりに表示させたい

先日担当した某病院様の案件で使用したTipsです。

その案件はWordPressでのCMSサイト構築だったのですが、PC/スマホの2デバイスでのレスポンシブ対応という事でした。
そこでメディアクエリで各デバイス毎のスタイルを作成していたのですが、
しかしその後でiPadなどのタブレットの場合にのみまた別のレイアウトにする+ランドスケープ表示の場合にはPC用のレイアウトにするということになりました。

これを整理すると以下のパターンになります。

  • PCで閲覧/タブレットでランドスケープ表示:PC用のスタイル
  • スマホで閲覧(縦横問わず):スマホ用のスタイル
  • タブレットでポートレート表示:タブレット用のスタイル

ここで困ったのが、タブレットでのviewportをどうするか?という問題です。

具体的に何が困ったのかというと

  • ランドスケープ/ポートレート毎にviewportは設定出来ない
  • デザイン上、ランドスケープ/ポートレート毎にデザインの min-width が変わってしまう
  • スマホでは width=device-width としているけど、そのままタブレットでも使うと縦横を変えたときにきれいに横幅が収まってくれない

といった問題が出てきました。

結論から言うと、viewportだけの制御は難しいと判断したのと、先行して作っていたPC/スマホ用の設計を崩したくないという事から
JavaScriptで対応する事としました。

[javascript]
$(function(){
var ua = navigator.userAgent;
if (ua.match(/iPad/) !== null || (ua.match(/Android/) !== null || ua.match(/Mobile/) === null)) {
$(window).bind(‘load orientationchange’, function(){
// タブレットで横表示(landscape)から縦表示の場合
if (Math.abs(window.orientation) === 90) {
$("html").css("zoom" , $(window).width() / ($(document).width()));
// タブレットで縦表示(portrait)の場合
} else {
$("html").css("zoom" , $(window).width() / 820);
}
});
}
});
[/javascript]

viewport をいじる、という事を最初は考えていましたが、JavaScriptが処理を終える前にviewportに応じてデバイス側でサイズを決定してしまうので
htmlドキュメントのzoomプロパティを強制的に変更するというものです。

10行目の820はタブレットのデザインでの横のサイズとなりますので、デザインに応じて任意の数値を指定してください。

また今回はタブレットだけで使用したいのでUAを取得してデバイスの判別が必要になります。
iPadはそのままですが、AndroidのタブレットはUAに「Android」が含まれており「Mobile」が無いものとなります。

また縦横の切り替えは orientationchange を bind して取得していますが、最初に画面を表示したときの向きに応じて変える必要もある
つまり表示後の縦横切り替えだけではダメなので「load orientationchange」を指定します。

 

これを設定した上で各デバイス毎にメディアクエリを使ってスタイルを定義してあげますが
メディアクエリの指定はこんな感じになりました。

[css]@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : portrait) {
}[/css]

横768px~1024pxのタブレットの場合で、かつ縦表示のみに限定するために and (orientation: portait) を追加しています。
 

ここまでスタイルを指定する条件が複雑になった場合は他の方法もあると思いますが
少々強引ですがこんな方法もある、というTipsでした。