← 記事一覧

viewportのmetaタグとは?正しい書き方と理由

モバイル向けviewport metaタグの役割、すべてのページに必要な1行、避けるべき値、viewport-fitやinteractive-widgetといった新しいオプションを解説します。

viewportのmetaタグは、モバイルブラウザに対して、ページのレイアウト領域の幅と最初の拡大率を指定するものです。ほぼすべてのWebサイトで、<head> に次の1行をそのまま書くべきです。

<meta name="viewport" content="width=device-width, initial-scale=1">

これがないと、スマホはページをPC向けのデザインとみなし、幅約980pxでレイアウトしてから画面に収まるよう縮小します。レスポンシブなCSSが効く機会がまったくありません。

viewport metaタグがないとどうなるか

スマホが登場した当時、ほとんどのWebサイトはPCの画面向けに作られていました。それを表示するために、モバイルブラウザはPCサイズの「レイアウトビューポート」(iOS版SafariとAndroid版Chromeでは980px)を持っているふりをし、ページ全体が画面に収まるよう縮小しました。ユーザーはピンチで拡大して読んでいたわけです。

この初期設定は、viewportタグのないページには今でも適用されます。画面幅390pxのスマホでは、そうしたページは次のようになります。

  • CSSやJavaScriptに対して、表示領域の幅を約980pxと伝える
  • (max-width: 600px) のようなメディアクエリに決して一致しない
  • 文字が本来のサイズの約40%で表示される

スマホでサイトが小さなPC版ページのように見えるなら、まずこのタグを確認しましょう。サイトがスマホで崩れる原因で取り上げている中でも、最もよくある原因です。

各値の意味

値 意味 推奨
width=device-width レイアウトビューポートを端末のCSSピクセル幅に合わせる(多くのiPhoneでは390など) はい
initial-scale=1 拡大率100%で開始し、1 CSSピクセルを1デバイス非依存ピクセルに対応させる はい
minimum-scale 許可する最小の拡大率 ほとんど不要
maximum-scale 許可する最大の拡大率 5未満の値は避ける
user-scalable=no ピンチによる拡大を無効にする 避ける
width=1024(固定値) レイアウト幅を固定する レスポンシブサイトでは避ける
viewport-fit=cover ノッチや角丸の下までページを広げる セーフエリアの余白とセットでのみ
interactive-widget 画面キーボードによるページのリサイズ方法を指定する 任意

拡大を無効にすべきでない理由

user-scalable=no や maximum-scale=1 は、ユーザーが拡大できないようにします。弱視の人にとってはページが読みにくく、あるいは読めなくなり、文字を200%まで拡大できることというWCAGの要件にも反します。Lighthouseのアクセシビリティ監査でも指摘されます。

開発者がこれを入れるのは、iOS版Safariがフォーム欄で自動的に拡大するのを防ぐためであることが多いのですが、正しい対処法は入力欄の文字サイズを16px以上にすることです。

input, select, textarea { font-size: 1rem; }

そもそも最近のiOS版Safariは、ピンチ拡大については user-scalable=no を無視するので、このタグは主にほかのブラウザに悪影響を与えるだけです。

viewport-fit=coverとセーフエリア

ノッチ、Dynamic Island、角丸のあるスマホでは、ブラウザはデフォルトでページを安全な長方形の中に収めます。viewport-fit=cover を指定するとページが画面全体を使えるようになり、画面端まで使うデザインでは便利です。その場合は、ノッチやホームインジケーターにコンテンツがかからないよう、自分で調整する必要があります。

<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
.site-header {
  padding-left: max(1rem, env(safe-area-inset-left));
  padding-right: max(1rem, env(safe-area-inset-right));
}
.bottom-bar { padding-bottom: env(safe-area-inset-bottom); }

ノッチが横に来る横向きでもテストしましょう。

interactive-widgetと画面キーボード

キーボードが開くと、ブラウザは視覚ビューポートだけを縮める(ChromeとSafariのデフォルト)か、レイアウト全体をリサイズします。新しい interactive-widget の値で、どちらにするかを選べます。

  • resizes-visual:デフォルト。レイアウトのサイズは変わらず、キーボードが一部を覆う
  • resizes-content:レイアウトビューポートが縮むので、100dvh の要素や固定フッターがキーボードの上に移動する
  • overlays-content:何もリサイズしない。VirtualKeyboard APIを使って自分で処理する

対応状況はブラウザによって異なります(Chromium系は対応。使う前に最新の対応状況を確認しましょう)。いずれにしても、フォームは実機でテストしてください。

削除してよい古い値

  • shrink-to-fit=no はiOS 9向けの回避策で、現在は効果がありません。
  • target-densitydpi は古いAndroid向けの値で、無視されます。
  • <meta name="HandheldFriendly"> と <meta name="MobileOptimized"> は、フィーチャーフォン時代のものです。

viewportタグの確認方法

  1. ページのソースを表示し、name="viewport" を検索します。ちょうど1つだけあるべきです。
  2. モバイルモードでLighthouse監査を実行します(手順)。viewportタグがない場合や拡大を妨げている場合に報告されます。
  3. スマホ表示でページを開きます。DevToolsのデバイスモードや、実際のスマホのサイズでページを読み込む Mobile View Extension で開くと、タグのないページは縮小され、文字が小さく表示されます。

よくある質問

正しいviewport metaタグは?

<meta name="viewport" content="width=device-width, initial-scale=1"> です。全画面のレイアウトを作り、セーフエリアに対応する場合にだけ viewport-fit=cover を加えます。

レスポンシブデザインにviewport metaタグは必要ですか?

必要です。ないと、モバイルブラウザはページを幅約980pxでレイアウトするので、モバイル向けのメディアクエリが一切適用されません。

user-scalable=noを使うのはよくないですか?

アクセシビリティの面でよくありません。ユーザーが文字を拡大できなくなります。フォーム欄での不要な拡大は、入力欄の文字サイズを16pxにして防ぎましょう。

次のサイトをモバイル表示で確認しましょう。

拡張機能を追加して、作業中のタブのまま端末プレビューを開けます。