スマホで崩れている=サイトが死んでいる
「〇〇さん、昨日納品してもらったサイトなんだけどさ、社長のスマホで見たらレイアウトがグチャグチャだって怒られちゃって……。今すぐ直せる?」
日曜日の朝9時、まどろみの中で受けたこの電話ほど、エンジニアの心臓に悪いものはありません。
当時の私は冷や汗をかきながら「す、すぐに確認します!」と飛び起き、Macbookを開きました。
Chromeの検証ツールでは綺麗に表示されている。iPhoneのシミュレーターでも問題ない。
でも、社長が持っている「数世代前のAndroid端末」でだけ、ハンバーガーメニューが閉まらなくなっていたり、メインビジュアルの文字が画面からはみ出していたりする。
これ、私が駆け出しの頃に何度も経験した「レスポンシブ地獄」の一コマです。
Web制作の現場において、「PCでは綺麗に見えるけど、スマホだと崩れる」というのは、もはやバグと同義です。いや、今の時代、アクセスの8割がスマホというサイトも珍しくないので、スマホで崩れている=サイトが死んでいると言っても過言じゃありません。
「レスポンシブなんて、メディアクエリで @media (max-width: 768px) って書くだけでしょ?」
もしあなたがそう思っているなら、あなたのエンジニア人生を救うことになるはずです。
今のレスポンシブデザインは、単に画面幅で切り替えるだけではありません。可変フォント、コンテナクエリ、画像の最適化、そして何より「あらゆるデバイスで見やすくする」というUX(ユーザー体験)の設計そのものなんです。
今回は、教科書的なコードの解説は最低限にして、私が15年の現場経験で培った「絶対に崩さないレスポンシブ構築の思考法」と「泥臭いトラブルシューティング」について、余すことなく語っていきます。
これを読み終わる頃には、あなたは「どんなデバイスでもかかってこい」と胸を張れるようになっているはずです。

「スマホ対応」はオマケじゃない、主役だ
まず最初に、マインドセットを叩き直す必要があります。
昔のWeb制作は「PCサイトを作って、ついでにスマホでも見れるようにする」という流れでした。
でも今は逆です。「スマホで完璧な体験を作って、画面が広いPCならもっとリッチに見せる」。これが現代のスタンダード、いわゆる「モバイルファースト」の本当の意味です。
クライアントはPCを見ない
私がフリーランスで直契約しているクライアントの話ですが、納品チェックの際、彼らはPCを開きません。
打ち合わせのカフェで、ポケットからiPhoneを取り出し、「うん、いい感じですね」と言って承認します。
つまり、いくらPC版で壮大なアニメーションを実装しても、スマホ版のボタンが小さくて押しづらかったら、その仕事は「0点」なんです。
Googleもスマホしか見ていない
SEO(検索順位)の観点でも、Googleは「モバイルファーストインデックス」という仕組みを導入しています。
これはざっくり言うと、「PCサイトの中身は見ないで、スマホサイトの中身だけを見て検索順位を決めるよ」というルールです。
スマホ版でコンテンツを省略していたり、読み込みが遅かったりすると、PC版がどれだけ立派でも検索順位は上がりません。
だからこそ、レスポンシブデザインは「エンジニアの嗜み」ではなく、「ビジネスの生命線」なんですよ。
最初に絶対に書くべき「魔法の1行」
技術的な話をしましょう。
レスポンシブデザインを始めるにあたって、HTMLの <head> タグ内に絶対に書かなければならない「魔法の1行」があります。
これがないと、どんなにCSSを頑張ってもスマホ対応はできません。
<meta name="viewport" content="width=device-width, initial-scale=1.0">
これが「ビューポート(Viewport)」の設定です。
これを書き忘れると、スマホのブラウザは「ああ、これはPC用のサイトだな」と判断して、Webサイト全体をギュッと縮小して表示してしまいます。結果、豆粒のような文字が表示されることになります。
初心者がやりがちなミスNo.1がこれです。
「CSS効かないんですけど…」と相談に来る後輩のコードを見ると、大体このメタタグが入っていません。
まずはこれをコピペする。そこから全てが始まります。
ブレイクポイントの正解はどこにある?
レスポンシブデザインの要となるのが、デザインを切り替える境目、つまり「ブレイクポイント」です。
「スマホ、タブレット、PCの3つに分けたいんですけど、何pxで区切ればいいですか?」
これ、現場でも永遠のテーマなんですが、私なりの結論をお伝えします。
細かく分けすぎるな
昔は、iPhone SE用(320px)、iPhone Plus用(414px)、iPad用(768px)、PC用(1024px)、大型モニター用(1440px)……と細かくメディアクエリを書いていました。
でも、これやると管理不能になります。新しいデバイスが出るたびにCSSを修正するつもりですか? 無理ですよね。
今の私の推奨は、以下の2つ(または3つ)だけです。
- モバイル(基本): 0px ~
- タブレット・PC兼用: 768px ~
- 大型PC(必要なら): 1200px ~
基本は「768px」という境界線一本で勝負します。
iPad(縦)の横幅が768pxなので、ここを基準にすることが多いです。
「スマホか、それ以外か」。これくらいシンプルに考えないと、コードがスパゲッティ状態になります。
悩ましい「iPad」の存在
一番厄介なのがタブレットです。
スマホのように指で操作するのに、画面サイズはPC並み。
ここでPC用のレイアウト(ホバーでメニューが開くなど)を適用すると、タップ操作でうまく動かずにハマることがあります。
なので、768px~1024pxあたりの領域は、「レイアウトはPC寄りだけど、操作性はスマホ寄り(ボタンを大きくする等)」という調整が必要になります。
ここを丁寧にやれるかどうかが、プロとアマチュアの分かれ目ですね。

脱・固定幅!「%」と「rem」と「clamp」を使いこなせ
レスポンシブで失敗する人のコードを見ると、大抵 width: 300px; のように「px(ピクセル)」で固定幅を指定しています。
pxは「絶対単位」なので、画面幅が変わっても頑としてサイズを変えません。それが画面からはみ出す原因になります。
横幅は「%」か「max-width」で管理する
要素の幅は基本的に width: 100%; にしておき、広がりすぎないように max-width: 1000px; といった制限をかけるのが鉄則です。
こうすれば、スマホでは画面いっぱいに(100%)、PCでは見やすい幅(1000px)に自動で収まります。
これを「リキッドレイアウト」と呼びます。レスポンシブの基礎中の基礎です。
文字サイズは「rem」が基本
フォントサイズに px を使うのも卒業しましょう。
今は rem(レム)を使います。これは「ルート(htmlタグ)の文字サイズに対する倍率」です。
通常、ブラウザの標準文字サイズは16pxなので、1rem = 16px になります。
なぜこれを使うかというと、ユーザーがブラウザ設定で「文字を大きく」していた場合、rem ならそれに合わせて自動で大きくなってくれるからです。アクセシビリティ(使いやすさ)の観点で必須です。
最強の関数「clamp()」
最近の現場で多用されているのが、CSSの比較関数 clamp() です。
これ、マジで便利です。メディアクエリを書かなくても、文字サイズや余白を可変にできるんです。
h1 {
/* 最小24px、推奨4vw(画面幅の4%)、最大48px */
font-size: clamp(24px, 4vw, 48px);
}
こう書くだけで、スマホでは24px、PCでは48px、その間は画面幅に合わせてなめらかに拡大縮小する見出しが作れます。
昔はメディアクエリで細かくfont-sizeを変えていましたが、今はこれ1行で済みます。
これを覚えた時、私は「CSS、進化しすぎだろ…」と感動して震えました。
FlexboxとGridでレイアウトを自在に操る
レスポンシブデザインにおいて、要素の並び替えは必須スキルです。
スマホでは縦並び、PCでは横並び。これを実現するために display: block と float を切り替えていたのは10年前の話。
今は Flexbox と Grid があります。
Flexboxで方向転換
Flexboxを使えば、flex-direction プロパティひとつで並び方向を変えられます。
.container {
display: flex;
flex-direction: column; /* スマホは縦並び */
}
@media (min-width: 768px) {
.container {
flex-direction: row; /* PCは横並び */
}
}
これだけです。
さらに order プロパティを使えば、「スマホの時だけ画像の順番を上にする」といったこともHTMLを変えずに実現できます。
デザイナーが「スマホ版はレイアウトを大きく変えたい」と言い出した時、この order プロパティを知っているだけで救われる命があります。
Gridで複雑なレイアウトも秒殺
もっと複雑な、雑誌のようなレイアウトにはCSS Gridが最強です。grid-template-columns を書き換えるだけで、2カラム、3カラム、4カラムと自由自在です。
.grid {
display: grid;
grid-template-columns: 1fr; /* スマホは1列 */
gap: 20px;
}
@media (min-width: 768px) {
.grid {
grid-template-columns: repeat(3, 1fr); /* PCは3列 */
}
}
昔はマージンの計算で電卓を叩いていましたが、今は gap プロパティで余白も一発。
もう margin-right: 20px をつけて、:last-child で右端のマージンを消す…なんて不毛な作業はしなくていいんです。

画像のレスポンシブ対応|重たい画像はギルティ
「サイトが重い」と言われる原因の8割は画像です。
特にレスポンシブの場合、PC用の巨大な画像をスマホで読み込ませるのはご法度です。
画面幅375pxのスマホに、横幅2000pxの画像を読み込ませる。これは、軽自動車にトラックのエンジンを積むようなもので、通信量の無駄遣いです。ユーザーのパケット代をドブに捨てさせてはいけません。
imgタグの基本
まずはCSSで画像の暴走を止めます。
img {
max-width: 100%;
height: auto;
}
これを全画像に適用します。これで画像が親要素からはみ出すことはなくなります。
pictureタグで画像を出し分ける
さらにプロフェッショナルな対応として、HTML側でデバイスごとに読み込む画像を切り替える手法があります。
<picture>
<!-- PC用(大きな画像) -->
<source media="(min-width: 768px)" srcset="large-image.jpg">
<!-- スマホ用(小さな画像) -->
<img src="small-image.jpg" alt="商品の写真">
</picture>
こう書くと、ブラウザが「お、今はスマホだから small-image.jpg だけダウンロードしよう」と判断してくれます。
PC用の画像はダウンロードすらされません。これにより、スマホでの表示速度が劇的に向上します。
GoogleのPageSpeed Insightsのスコアを上げたければ、この実装は必須です。
ハンバーガーメニューの是非と実装ポイント
スマホサイトの代名詞とも言える「ハンバーガーメニュー(三本線アイコン)」。
これ、実はUX的には賛否両論あるんです。
「メニューが隠れていることに気づかない」「タップ数が増える」というデメリットがあるからです。
本当にハンバーガーが必要か?
項目数が3つ~4つなら、ヘッダーやフッターにアイコンを並べて常に表示しておいた方が、ユーザーにとっては使いやすい場合があります(アプリのようなUI)。
「スマホ=ハンバーガー」と思考停止せず、「ユーザーが一番使いたい機能は何か?」を考えるのが設計者の仕事です。
実装の落とし穴
もしハンバーガーメニューを実装するなら、以下の点に注意してください。
- アイコンは大きく:指でタップしやすいよう、最低でも44px × 44pxの判定を持たせる。
- 開いた時の背景固定:メニューを開いた状態でスクロールすると、後ろのコンテンツまでスクロールしてしまう現象(スクロール貫通)。これをJavaScriptで防ぐ処理を入れないと、操作性が最悪になります。
// メニューが開いている時はbodyのスクロールを止める例
if (isOpen) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = '';
}
こういう細かい配慮ができるかどうかが、「使いやすいサイト」と「なんかイライラするサイト」の差になります。

現場のリアル|実機検証という名の泥沼
Chromeの検証ツール(デベロッパーツール)は優秀です。
デバイスモードを使えば、iPhoneやGalaxyの表示をシミュレートできます。
でも、断言します。「シミュレーターだけで納品するのは絶対にやめろ」。
実機でしか起きないバグがある
シミュレーターはあくまで「ブラウザの幅を変えて見せているだけ」です。
実際のアンドロイド端末の癖や、iPhoneのSafari特有のバグ(100vh問題など)までは再現してくれません。
私が経験した恐怖体験として、iPhoneの実機で見た時だけ、特定の背景画像がガビガビに引き伸ばされて表示されるバグがありました。
原因は background-attachment: fixed; というプロパティがiOSと相性が悪かったこと。
これは実機で見ない限り、一生気づけなかったバグです。
検証端末どうする問題
とはいえ、個人で全機種揃えるのは無理ですよね。
最低限、自分の持っているスマホと、家族や友人の違うOSのスマホを借りてチェックするくらいはやりましょう。
本格的に案件を受けるなら、「BrowserStack」のようなクラウド検証ツールを使うのも手です。月額料金はかかりますが、納品後のクレーム対応にかかる時間を考えれば安い投資です。
クライアントとの戦い|「スマホで見にくい」と言われたら
技術的なこと以上に難しいのが、クライアントとのコミュニケーションです。
特にレスポンシブデザインにおいては、認識のズレが頻発します。
「ロゴをもっと大きくして」の罠
クライアントは自分の会社のロゴを愛しているので、「スマホでもロゴを大きく目立たせて」と言ってきがちです。
でも、スマホの狭い画面でロゴを巨大化すると、肝心のコンテンツが下に追いやられてしまいます。
ここで「分かりました」とイエスマンになってはいけません。
「ロゴを大きくすると、お客様が一番見たい『商品一覧』がファーストビューに入らなくなります。結果的に売上に悪影響が出ますが、それでもよろしいですか?」
と、あくまで「ユーザーの利益」を盾にして説得するのです。
エンジニアはただコードを書くだけでなく、サイトの価値を守るガードマンでもあります。
テキスト量の調整
PCでは1行で収まっていたキャッチコピーが、スマホでは3行になってレイアウトを圧迫する。これもよくあります。
CSSで文字サイズを小さくするのには限界があります。
時には、「スマホ用に短いキャッチコピーを用意してもらえませんか?」と提案する勇気も必要です。
デザインのためにコンテンツを変える。本末転倒に見えるかもしれませんが、スマホという極小の画面で情報を伝えるためには、そこまで踏み込む必要があるんです。

これからのレスポンシブ|コンテナクエリという革命
最後に、少し未来の話をします。
これまでのレスポンシブは「画面幅(ビューポート)」を基準にしていました。
しかし、今まさに普及し始めている「コンテナクエリ(Container Queries)」は、この常識を覆します。
これは、「親要素(コンテナ)の幅」に応じてスタイルを変えられる技術です。
例えば、サイドバーに置かれた時は「縦並びのカード」、メインエリアに置かれた時は「横並びのカード」といった具合に、部品単位でレスポンシブな挙動を定義できます。
.card-container {
container-type: inline-size;
}
@container (min-width: 500px) {
.card {
/* 親要素が500px以上なら横並びにする */
display: flex;
}
}
これが標準になれば、画面幅を気にするメディアクエリ地獄から解放され、より再利用性の高いコンポーネントが作れるようになります。
まだ全てのブラウザで完全にサポートされているわけではありませんが、知識として持っておくと「お、こいつ最先端を追ってるな」と思われますよ。
結局、現場で大切なこと
長々と技術的な話をしてきましたが、レスポンシブWebデザインの本質は「思いやり」です。
「電車の中で片手で操作する人は、ここにボタンがあったら押しやすいかな?」
「通信制限がかかっている人は、この画像が表示されるまでイライラしないかな?」
「老眼の人は、この文字サイズだと読みづらいかな?」
コードを書くとき、画面の向こうにいる生身の人間をどれだけ想像できるか。@media の中に書くCSSプロパティの一つひとつは、ユーザーへのラブレターみたいなものです。
崩れているサイトというのは、手紙の字が汚くて読めないのと同じ。それでは気持ちは伝わりません。

私も最初は失敗ばかりでした。納品後に「文字が小さすぎて読めん!」と怒鳴られたこともあります。
でも、そうやってユーザーの反応を肌で感じて、修正して、また反応を見る。その泥臭い繰り返しの先にしか、本物のスキルはありません。
今、あなたの手元にあるその崩れたレイアウト。
それは面倒なバグじゃなくて、あなたがプロになるための最高の練習台です。
検証ツールを開いて、原因を突き止めて、修正してやってください。
スマホで綺麗に表示された瞬間の、「よしっ!」というガッツポーズ。あの快感を味わってほしいんです。
さあ、エディタに戻りましょう。あなたの書くコードが、世界中の誰かのスマホの中で、最高の体験を作ることを願っています。
