今日は本当に驚くべき体験をした。普段通り window.innerWidth を使ってブラウザの幅を測定し、768px以下の場合は isMobile = true になるようにコードを書いた。テストも徹底的に行った。iPhone、GalaxyなどのさまざまなデバイスでSafari、Chrome、Braveブラウザを試し、問題がないことを確認した。

しかし…

知人が突然、私のウェブアプリケーションがGalaxyの Samsungブラウザ で奇妙に見えると教えてくれた。「まさか?」と思ったが、実際にテストしてみると 本当にSamsungブラウザではモバイル環境でも window.innerWidth < 768 がfalseになる 奇妙な状況が発生した。

理解できなかった。Samsungブラウザだけでそんなことが起こるのも奇妙だが、 PCのChromeとFirefoxブラウザで開発者モードでモバイル画面を確認してもfalseが返ってくること を発見した。

スマートフォンでウェブサイトをテストしている開発者


問題解決のためのさまざまな試み

私はすぐに別の方法を試してみた。

1. window.innerWidth

const isMobile = window.innerWidth < 768;

✅ 一般的なブラウザでは正常に動作
SamsungブラウザとPCのChrome/Firefox開発者モードではfalseを返す(失敗)

2. document.documentElement.clientWidthを追加

const isMobile = (window.innerWidth || document.documentElement.clientWidth) < 768;

✅ 論理的により安全なコード
依然としてSamsungブラウザと開発者モードでfalse(失敗)

3. window.matchMedia('(max-width: 767px)')を使用

const isMobile = window.matchMedia('(max-width: 767px)').matches;

すべてのブラウザで正常に動作!(成功 🎉)

この結果を見て、私は結論を出した。
今後、モバイルかどうかを判断するには window.matchMedia を使用するべきだ。


なぜこのようなことが起こるのか?

正直に言えば、ブラウザの内部ソースを直接見なければ正確な原因を知るのは難しい。しかし、推測することはできる。

  1. Samsungブラウザのレンダリング方式の違い
    SamsungブラウザはChromiumベースだが、さまざまなカスタム最適化が加わっている。この過程で window.innerWidth の値が一般的なモバイルブラウザと異なって動作する可能性がある。

  2. PCのChrome & Firefox開発者モードで発生した理由
    開発者モードで「モバイル画面表示」機能を有効にすると、ブラウザは画面サイズを調整するだけでなく、内部的にさまざまな設定を変更する。しかし、すべての環境が実際のモバイルデバイスを100%完璧にエミュレートするわけではない。開発者モードでの window.innerWidth の値が実際のデバイスと異なって動作する理由かもしれない。

  3. スクロールバーの含まれるかどうかの違い
    window.innerWidth はビューポートの幅を含むが、 document.documentElement.clientWidth はスクロールバーを除いた実際のコンテンツの幅を返す。
    Samsungブラウザは内部的にスクロールバーを別の方法で処理しているのではないか?しかし、その仮説だけではすべての現象を説明できなかった。

結論として…


今後、モバイルかどうかをチェックする時は matchMedia を使おう

この体験を通じて window.innerWidth のような方法は信頼できないことを実感した。
今後、モバイル環境を判断する際は以下のように matchMedia を使用するのが安全だ。

const isMobile = window.matchMedia('(max-width: 767px)').matches;

📌 この方法を使うと
✅ すべてのブラウザで正常に動作する。
✅ 開発者モードでも一貫した結果を得られる。
✅ Samsungブラウザのような特殊な環境でも問題なく動作する。

時には、これらの予期しないバグとの出会いが良い開発者になるプロセスだと思う。とにかく今日は Samsungブラウザのおかげで(?) matchMedia の必要性に気づいた。 😆