スマホでゲーム画面がはみ出すときの直し方:縦横比と余白の設計
遊びをつくる執筆にClaudeを使用しています。

PCのブラウザで完璧に見えていたゲームをスマホで開いたら、右端が切れていた——そんな経験はよくあります。原因はほぼ決まっていて、「画面の広さを前提に固定ピクセルで組んでいること」と「ブラウザがスマホ向けに幅を調整する仕組みを無視していること」の組み合わせです。この記事では、はみ出しが起きる理由を整理したうえで、viewportの設定・CSSの単位・縦横比の確保という3段階の対策を説明します。コード例は説明用の簡略版です。実際のゲームへ適用する前に、ご自身の環境で動作を確認してください。
この記事の目次
なぜスマホでゲームがはみ出るのか
デスクトップブラウザは画面幅がそのままCSSの基準になります。一方、スマホのブラウザは何も指定しないと「仮想的な980px幅」でページをレンダリングし、それを画面に収まるよう縮小します。この動作があるため、PC向けに1200pxや800pxで固定したゲーム画面は「まず980pxの仮想空間に収まらない」状態になり、横スクロールバーが出たり右端が切れたりします。
もう一つの原因は、ゲームのcanvasや外側のラッパー要素に 固定ピクセル(例:width: 800px) を使っていることです。固定ピクセルの要素は画面幅に合わせて縮まないため、デバイス幅が400pxのスマホでは単純にはみ出します。ゲームの遊技領域(canvasなど)と、その周りのUI(ボタン・スコア表示)を別々のレイヤーで管理している場合、どちらかだけ対処しても結果は中途半端になります。設計の段階から「画面全体をどう分割するか」を考えることが必要です。
第一歩:viewportメタタグでブラウザの仮想幅を解除する
まずHTMLのheadにviewportメタタグがあるかを確認してください。このタグがないか、widthの指定が不適切だと、ブラウザは980pxの仮想幅を使い続けます。
<meta name="viewport" content="width=device-width, initial-scale=1">このタグを追加するだけで「CSSのピクセル基準がデバイスの実際の幅になる」という変化が起きます。例えばiPhoneの多くはCSS上の幅が375〜430px程度になり、それがCSSの1vw・100%の基準になります。既存のゲームにこのタグが入っていない場合、まずここから試すのが最短経路です。
user-scalable=noやmaximum-scale=1を追加してピンチズームを無効にする方法が紹介されることがありますが、MDNのドキュメントはアクセシビリティの観点からズームを最低2倍は許可するよう推奨しています。ゲームの操作性を優先するあまりズームを完全に禁止すると、弱視のユーザーがゲームを利用できなくなる場合があります。
第二歩:固定pxをやめてスケールするCSS単位へ切り替える
viewportメタタグを設定したら、次はゲームの最外側ラッパーとcanvasの幅・高さをビューポート相対単位に書き換えます。主な選択肢は次のとおりです。
- vw(viewport width):ビューポート幅の1%。横幅いっぱいに広げたいときは width: 100vw 。
- vh(viewport height):ビューポート高さの1%。ただしスマホのアドレスバーが出入りすると値が変化します。
- svh / dvh / lvh:CSS Values Level 4で定義された派生単位。svhはアドレスバーが出た状態の最小高さ、dvhは動的に変化、lvhはアドレスバーを除いた最大高さを指します。
- vmin:vwとvhの小さいほう。正方形のゲームを縦向き・横向き問わず収めたいときに便利です。
- % + max-width:width: 100%; max-width: 800px; の組み合わせ。PCでは上限を保ちつつスマホでは伸縮します。
アドレスバーの影響を受けやすい縦スクロールなしのゲームでは、高さ方向にvhの代わりにsvhを使うことで「バー出現時に画面が縦に縮んでUI要素が隠れる」問題を緩和できます。ただしsvh・dvh・lvhはすべてのブラウザで利用できるようになった時期が比較的新しいため、対象ユーザーの環境を踏まえて選択してください。
第三歩:縦横比をCSSで固定してゲーム領域が崩れないようにする
幅をパーセントやvwで指定しても、高さを連動させなければcanvasが正方形に変形したり、意図した縦横比が崩れたりします。CSSのaspect-ratioプロパティを使うと、幅に対して高さを自動計算させながら比率を維持できます。
/* 説明用のサンプルです。実際のゲームに合わせて調整してください */
.game-wrapper {
width: 100%;
max-width: 800px;
aspect-ratio: 4 / 3; /* ゲームの設計比率に合わせて変更 */
margin: 0 auto;
overflow: hidden;
position: relative;
}
canvas {
width: 100%;
height: 100%;
display: block;
}ゲームを16:9で設計した場合は aspect-ratio: 16 / 9、正方形なら 1 / 1 のように設計時の比率をそのまま書きます。このパターンでは、外側のラッパーが画面幅に応じた正しいサイズになり、canvasは幅・高さ100%でラッパーを埋めます。ゲームのロジック側(JavaScript)で描画する際も、canvasのclientWidthとclientHeightを読んでスケールを合わせれば、内部座標系とCSS表示サイズのズレが起きません。
なお、aspect-ratioが効くのは幅か高さのいずれかがauto(または省略)の場合です。width・heightを両方固定ピクセルで指定すると、縦横比の計算が無効になります。
ノッチとホームバー:safe-area-insetで操作UIを逃がす
iPhone(Dynamic Island・ノッチ型)やAndroidの一部機種は、画面の四隅や上下にシステムUIが重なる領域を持っています。ゲームのボタンがちょうどそこに配置されると、タップが反応しなかったり見切れたりします。CSSのenv()関数を使うと、デバイスが提供する安全領域(セーフエリア)のサイズを取得してpaddingやmarginに反映できます。
/* viewportメタタグにviewport-fit=coverが必要です */
.game-ui-bottom {
padding-bottom: env(safe-area-inset-bottom, 0px);
}
.game-ui-top {
padding-top: env(safe-area-inset-top, 0px);
}env()のセーフエリア変数を使うには、viewportメタタグのcontentにviewport-fit=coverを追加する必要があります(例:content="width=device-width, initial-scale=1, viewport-fit=cover")。ゲームエリア自体は画面端まで広がり、UIだけセーフエリア分だけ内側に寄る設計になります。
遊技領域とUIの分離:設計の考え方
はみ出しの修正を繰り返さないための設計の軸は「遊技領域(canvas)とオーバーレイUI(ボタン・スコア)を別レイヤーで重ねる」です。canvasはaspect-ratioで比率を固定してスケールさせ、UIはposition: absoluteやCSSグリッドで四隅や中央に配置します。こうすると、画面サイズが変わったときにcanvasが縮むだけで、UIの配置ロジックは変えなくて済みます。
もう一つ意識したいのが「最小プレイ幅」の設定です。ゲームによっては320pxや360px以下では操作が成立しないことがあります。そうした場合は min-width に加え、横幅が足りないときにメッセージを表示するCSSクラスを用意しておくと、制作側も対応範囲を明示できます。実際にどこまで対応するかはゲームのUIの複雑さと、想定するプレイヤーのデバイスの分布によって変わります。
確認の手順
- PCブラウザの開発者ツールでデバイスエミュレーションを開き、「iPhone SE(375px)」「iPhone 14 Pro(393px)」「Pixel 7(412px)」など複数の幅でレイアウトを確認する。
- 縦向き(portrait)と横向き(landscape)を切り替え、縦横比が崩れていないか確認する。
- 実機(または実機相当のブラウザ)でアドレスバーのスクロール出入りを起こし、ゲームエリアの高さが意図した通りに保たれているか確認する。
- ゲームUIのボタンやインタラクティブな要素がセーフエリアに隠れていないかを確認する。
開発者ツールのエミュレーションはあくまで近似値であり、実際のデバイスと動作が異なることがあります。特にアドレスバーの挙動やセーフエリアの反映は、実機で確認するほうが確実です。デバイスエミュレーションで問題がなかったとしても、実機テストを省く理由にはなりません。
アソバースにゲームをアップロードしたあとも、スマホのブラウザで実際に開いてプレイ画面を確かめるのが最終確認の基本です。HTMLファイル単体の場合も、ZIPファイルでまとめたマルチファイル構成の場合も、表示の仕組みはWebの標準に従います。今回紹介したviewportメタタグとCSS単位の対応は、どちらの投稿形式でも共通して効果があります。




