レスポンシブ対応におけるビューポート制御

goran

@goran_nasai

こんにちは。GORAN です。今日はviewportについての話をします。

レスポンシブ対応ってつらいですよね。ほとんどのWeb制作現場では、PC・SPそれぞれひとつのwidthに対してのみのデザインカンプしかなく

  • それより大きくなったとき
  • それより小さくなったとき

というのはマークアップのエンジニアがよしなに対応するしかない状況と思います。

かくいう弊社も、ことLPについては

  • PC - width:1920px
  • SP - width:375px

の1組でデザインがあがってくるケースがほとんどでして、タブレットなど中間層の対応や375px以下の対応はエンジニアに委託されています。

特にSPについては、375pxで作ったデザインは350px以下のデバイスでほぼ間違いなく崩れますので、ツラすぎます。

レスポンシブとは?

1つのスタイルシートと1つのHTMLでどのデバイス・ブラウザからアクセスしても最適な表示がされている状態(だと信じています)。リダイレクトはもってのほかですが、メディアクエリでスタイルシートを出し分けするようなやり方もレスポンシブとは呼べないと思ってます。

そんな状況を解決に導くviewportの設定をご紹介します。

やり方はふたつありまして、どちらもjsviewportを制御する方法です。

  • 375px以下を諦める
  • userAgentで出し分け

いずれもLPマークアップに際してはよく使っています。

375px以下を諦める

潔く375pxより小さいデバイスでは375pxだと思って表示してねというやり方です。 弊社では上述の通り、SPデザインを375pxで作成しているため、375pxのままshrinkさせることにしていますが、 Android標準は360pxだったりするので、閾値を360にするケースもアリだと思います。

コード

js
  const viewport = document.querySelector('meta[name="viewport"]');
  function fixViewport() {
    const value =
      window.innerWidth > 375
        ? 'width=device-width,initial-scale=1'
        : 'width=375';
    if (viewport.getAttribute('content') !== value) {
      viewport.setAttribute('content', value);
    }
  }

参考

以下のツイート。2点差異があります。

より広範囲にレスポンシブコーディングについてまとめられたこちらの記事も参考になります。弊チームもマークアップでここまで徹底できる現場にしたい。

userAgentで出し分け

冒頭で否定した内容ですが、LPのマルチデバイス対応ではスタイルシートを2つ用意してメディアクエリを使って適用するスタイルを変えるというやり方がまだまだ主流だと感じます。

その場合のビューポート制御についてはuserAgentによる出し分けが、特にタブレットでの挙動について安定する気がしてます。(タブレットではPCでの表示をそのままshrinkさせるなど、デザインである程度割り切っている状態が前提です)

コード

js
const viewport = document.querySelector('meta[name="viewport"]');
const os = function () {
    var ua = navigator.userAgent,
        isAndroid = /(?:Android)/.test(ua),
        isiPhone = /(?:iPhone)/.test(ua),
        isPhone = (isAndroid && /(?:Mobile)/.test(ua)) || isiPhone,
        isFireFox = /(?:Firefox)/.test(ua),
        isChrome = /(?:Chrome|CriOS)/.test(ua),
        isSafari = /(?:Safari)/.test(ua),
        isTablet = /(?:iPad|PlayBook|)/.test(ua) || (isAndroid && !/(?:Mobile)/.test(ua)) || (isFireFox && /(?:Tablet)/.test(ua)) || (isSafari || isChrome && typeof document.ontouchstart !== 'undefined' ),
        isPc = !isPhone && !isTablet;
    return {
        isTablet: isTablet,
        isPhone: isPhone,
        isPc: isPc
    };
}();
if (os.isPhone) {
    viewport.setAttribute('content', 'width=375');
} else if (os.isTablet) {
    viewport.setAttribute('content', 'width=1300');
} else if (os.isPc) {
    viewport.setAttribute('content', 'width=device-width,initial-scale=1');
}

留意

SymbianWindows Phoneにも対応したい場合は付け加えてください。

とはいえ

上記の手法は根本的なレスポンシブコーディングのツラさに対する万能薬にはなり得ません。(あくまでLPなどの単体かつ静的なページデザインに対しての特効薬的なもの)

根本が解決された夢のような開発体験には

  • ブレイクポイントについて理解のあるデザイナー
  • UI/UXデザインについて理解のあるエンジニア

双方の歩み寄りが必要不可欠であるはずです。弊チームとしてはまだまだユートピアですが、直向きに歩みを進めていきたいです。向かおうとする意志だけは絶やしちゃいけないので。