knowledge base

マークアップ/フロントエンドエンジニアのWEB制作における備忘録です。平日はWEB屋、休日は社会人劇団の主宰・劇作家をしています。

Androidデフォルトブラウザでviewportが無視される

たとえば下記のようなページを想定します。

 

f:id:ShinImae:20160108163451j:plain

ビジュアルが表示幅ぴったりに広がっており、とても洗練されたデザインですね。

今回はこのデザインを横幅320pxに最適化して表示する際の問題について書きたいと思います。

横幅320pxに最適化とは

横幅320px固定のデザインを、各デバイスの幅に合わせてフィットさせることを言います。

具体的には次の指定をすることで最適化を行います。

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

この指定により、横幅320px固定でコーディングしても、各デバイスの幅にぴったりフィットします。

ところが、デバイス幅が320px以上のAndroid端末(デフォルトブラウザ)で表示すると下図のようにviewportの指定が無視されてしまい、ページ両端に余白が生じてしまいます。

f:id:ShinImae:20160108163458j:plain

 

どうやらAndroidデフォルトブラウザのもつバグのようで、AndroidGoogleChromeFirefoxでは、デバイスの横幅にぴったりフィットします。

この問題を解決するには2段階の方法をとります。

  1. Androidデフォルトブラウザのみを判別できるようにする
  2. コンテンツがデバイスの横幅にフィットするように拡大するような指定をかける

では、ひとつづつ解決法を見てゆきましょう。

Androidデフォルトブラウザの判別

あまり知られてはいませんが、IE,Chrome,FireFoxと同様にデフォルトブラウザもUserAgentから判別できます。

こちらの記事で詳しく解説されているとおり、どうやら「linux; u;」という文字列が含まれていればデフォルトブラウザであるようです。

yoyogisan.hatenablog.com

まずは下記方法で、デフォルトブラウザを判別します。

var ua = window.navigator.userAgent.toLowerCase();
if(ua.indexOf('linux; u;') != -1){
    return true;
}

より確実に判別したいなら、OSがAndroidであるか判別した上で、デフォルトブラウザであるかどうかを判定します。

var ua = window.navigator.userAgent.toLowerCase();
if(ua.indexOf('android') != -1){						
   if(ua.indexOf('linux; u;') != -1){
      return true;
   }
}

横幅にフィットするように拡縮指定をする

横幅320pxに対する現在のウィンドウ幅の比率を算出し、その比率だけ拡縮するようにします。ロジックは次のとおり。

var windowWidth = $(window).width();
var ratio = windowWidth/320;
$('html').css({'zoom' : ratio });

今回はウィンドウの横幅を320で除算していますが、viewportのサイズによってこの値は変化します(たとえば640pxで最適化をするなら640で除算します)。

こうすることで、小さなデバイスでは縮小され、大きなデバイスでは拡大されます。

これを、先ほどご紹介したデフォルトブラウザ判別方法に組み込みます。

var ua = window.navigator.userAgent.toLowerCase();
var windowWidth = $(window).width();
var ratio = windowWidth/320;
if(ua.indexOf('android') != -1){						
   if(ua.indexOf('linux; u;') != -1){
      $('html').css({'zoom' : ratio });
   }
}

こうすることで、デフォルトブラウザでもねらい通りの表示を実現することができます。