マガジン

スマホで遊べるブラウザゲームの作り方:縦画面設計の基本

遊びをつくる

執筆にClaudeを使用しています。

キーボードとタッチの二つの入力が、同じ駒のジャンプにつながる様子を描いたイラスト。
記事のテーマをもとに制作したAI生成イラスト。

ブラウザゲームをスマホで公開しても「画面がはみ出す」「ボタンが小さすぎて押せない」という声が届く。原因の多くは、PCの横長レイアウトをそのまま持ち込んでいることにあります。スマホユーザーの大半は縦持ちでページを開くため、横幅360〜430px前後の縦長の空間をゲームの「ステージ」として最初から設計し直す必要があります。 この記事では、縦画面(ポートレートモード)を前提にしたブラウザゲームのレイアウト設計を、HTML・CSS・JavaScriptの範囲で具体的に説明します。すでにゲームのロジックはある程度できていて、「スマホで快適に遊べる状態にしたい」という段階の人を主な読者として想定しています。

この記事の目次
  1. なぜ縦画面を「前提」にするのか
  2. viewport設定とCSSの基礎を整える
  3. ゲームエリアのサイズをどう決めるか
  4. タッチ操作のUI設計で外せない3つの判断基準
  5. 縦画面でよく崩れる場所と対処
  6. 次の行動
  7. 参考資料

なぜ縦画面を「前提」にするのか

横画面を基準にしてから縦画面に対応しようとすると、UIの組み替えが二重に発生します。最初から縦画面を基準にして設計し、余裕があれば横画面を追加対応するほうが工数は少なくなります。

スマホの縦画面で確保できる実質的な表示領域は、機種やブラウザのUIによって変わります。一般的な目安としては、横幅360〜430px・高さ600〜750px程度を安全な最小サイズとして考えておくと、多くの機種で崩れにくくなります。この数字を「ゲームキャンバスの最小保証サイズ」として頭に入れておくのが出発点です。

viewport設定とCSSの基礎を整える

HTMLの<head>に次の1行がない場合、スマホブラウザは画面をPC幅と見なして縮小表示します。これがはみ出しや文字の極小化の最大の原因です。

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

user-scalable=noを加えてピンチズームを禁止する実装も見かけますが、アクセシビリティの観点から推奨されないことが多く、ゲームによっては不要な場合もあります。ピンチで壊れる場面が限られるなら、禁止せず動作確認だけ行うほうが無難です。

CSSのリセットとして、次の2行を早めに書いておくと余計なスクロールバーやはみ出しを防げます。

css
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; overflow: hidden; }

overflow: hiddenはスクロールを完全に封じるため、ゲーム全体がビューポート内に収まる設計が前提になります。スクロールが必要な画面(メニュー・ランキング表示など)では、その要素だけoverflow-y: autoを使い分けます。

ゲームエリアのサイズをどう決めるか

縦画面ゲームの典型的なアプローチは二つあります。

固定サイズ+CSS拡縮

ゲームの論理サイズを固定値(例:360×640px)で設計し、実際の画面サイズに合わせてCSSのtransform: scale()で拡大縮小します。ゲームロジック内の座標計算がシンプルになり、Canvasを使うゲームとの相性が良いのが利点です。

css
#game-container {
  width: 360px;
  height: 640px;
  transform-origin: top left;
  /* JSでscaleを動的に設定する */
}

JavaScriptではwindow.innerWidth / 360とwindow.innerHeight / 640の小さい方を係数としてscale()に渡します。resizeイベントで再計算するのも忘れないようにします。

可変サイズ(フレックス・グリッドレイアウト)

UIをCSSのflexboxやgridで組み、要素が画面サイズに応じて伸縮する設計です。パズルやカード系など、ゲームエリアがタイル状に分割できる場合に向いています。vw・vh・clamp()を組み合わせると、極端な画面サイズでも崩れにくくなります。

css
#game-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(4px, 1.5vw, 12px);
  width: 100%;
  max-width: 430px;
  margin: 0 auto;
}

どちらを選ぶかは「ゲームロジックが座標ベースか否か」で判断します。Canvasに描画するアクションゲームなら固定サイズ+拡縮、DOMを並べるボードゲームやカードゲームなら可変サイズが扱いやすいです。

タッチ操作のUI設計で外せない3つの判断基準

タップ領域は最低44×44px

ボタンや操作パネルのタップ領域が小さいと、指の太さの違いでミスタップが連発します。Apple・Googleともにタップターゲットの推奨最小サイズとして44〜48px程度を挙げています。視覚的なボタンが小さくても、paddingや透明な::after疑似要素で当たり判定を広げることができます。

css
.tap-button {
  min-width: 44px;
  min-height: 44px;
  padding: 12px 20px;
}

親指の届く範囲にコアな操作を置く

縦持ちのスマホを両手で持った場合、画面上部は親指が届きにくい領域です。ゲームの主要な操作ボタン(攻撃・決定・ジャンプなど)は画面下半分、特に左右の端に配置するとストレスが減ります。設定やポーズボタンは誤タップしても被害が少ないため、上部に置いて構いません。

`pointer-events`と`touch-action`を明示する

スワイプ操作を使うゲームでは、ブラウザのデフォルトスクロール動作と競合しやすいです。スワイプを使う要素にはtouch-action: noneを指定してブラウザへの伝搬を止めます。逆に縦スクロールを残したいメニュー画面ではtouch-action: pan-yを使います。設定を省略すると機種・ブラウザによって挙動が変わるため、明示する習慣をつけると動作確認が楽になります。

縦画面でよく崩れる場所と対処

高さの計算に100vhを使ったら画面が溢れた:モバイルブラウザのアドレスバーが100vhの計算に含まれないことがあり、実際の表示領域より高さが大きくなります。100svh(Smallest Viewport Height)を使うと、常にアドレスバーを除いた高さを取れます。ただし対応ブラウザを確認してから採用してください。

横スクロールが出る:要素に固定幅やネガティブマージンが残っているときに起きます。document.documentElement.scrollWidth > window.innerWidthをコンソールで確認し、原因要素をoutline: 1px solid redで探すと素早く特定できます。

フォントが極小になる:iOSのSafariはfont-sizeが小さいと自動拡大することがあります。bodyにtext-size-adjust: 100%(-webkit-text-size-adjust: 100%)を加えておくと防げます。

向きが変わったときにレイアウトが崩れる:orientationchangeイベントやscreen.orientationAPIでの検知後、意図的に「縦画面のみ対応」のメッセージを表示する方法があります。横回転に対応しないゲームならば、横向きを検知したら「縦向きに戻してください」と案内するだけで済み、横レイアウトの対応工数を省けます。

次の行動

まずviewportメタタグとbox-sizingのリセットが入っているかを確認し、ゲームエリアのサイズ設計方針(固定+拡縮 or 可変)をロジックの種類に合わせて選んでください。タップ領域の最小サイズとtouch-actionの設定は後回しにしがちですが、実機確認の前に入れておくと手戻りが少なくなります。仕上がったゲームはZIPまたはHTMLファイルとしてアソバースに投稿し、スマホの実機でプレイ画面を確かめてみてください。

参考資料

  • MDN Web Docs「viewport meta tag」
  • MDN Web Docs「touch-action」
  • Apple Human Interface Guidelines「Targets」
  • Google Material Design「Touch targets」
  • MDN Web Docs「CSS Values and Units: Viewport-percentage lengths(svh)」