再現性のないバグの犯人を特定する方法|デバッグの裏技と心構え

C
クリオ
Web制作ディレクター / フロントエンジニア

こんにちは!

今日は「再現性のないバグの犯人を特定する方法」について解説します。

これ、ほんまにめっちゃ困るやつですよね。
「自分の環境では大丈夫なんですけど…」「時々崩れるんですけど原因がわかりません…」
こういった再現性のないCSSバグって、現場で最も厄介な問題の一つなんです。

再現性のないバグが生まれる理由

僕も昔、営業さんから「ユーザーの報告では崩れてるんです」と言われて、自分のPCで何度確認してもどうしても再現できなくて、めっちゃ焦ったことあります。
その時にわかったのは「再現性がない = 条件が限定的」っていう大事な法則なんです。

再現性のないバグって、実は原因は確実に存在してるんですよ。
ただ、その条件が:

  • 特定のブラウザでだけ発生する
  • 特定の画面サイズでだけ発生する
  • キャッシュが溜まった状態でだけ発生する
  • 特定のOSやデバイスでだけ発生する
  • JavaScriptが特定の順番で実行された時だけ発生する

こういった限定的な条件なので、見つけにくいわけです。
だからこそ、僕たちは「体系的に条件を絞っていく」というアプローチが必要になります。

環境差分を疑う:ブラウザとキャッシュの落とし穴

再現性のないバグに直面したら、まず真っ先にやるべきことが「環境を変える」です。

これはめっちゃ重要なので、チェックリストを作っておきました。

ブラウザの切り替え

Chrome、Safari、Firefox、Edgeで順番に開いてみてください。
意外かもしれませんが、ブラウザによってCSSの解釈が微妙に違うことがあります。
特に line-heightletter-spacingtransform の挙動は要注意です。

キャッシュのクリア

これ、現場で何度も経験してます。
古いCSSがブラウザに残ってて、新しいファイルが読み込まれてないパターンですね。

デベロッパーツールで「Network」タブを開いて、ステータスコードを確認するといいですよ。
もし 304 Not Modified が出てたら、キャッシュが効いてる状態です。

確実にクリアするには:

  • DevTools で右クリック → 「キャッシュを空にしてハード再読込」を選択
  • または Ctrl + Shift + Delete(Windows)/ Cmd + Shift + Delete(Mac)でブラウザキャッシュを直接削除

デバイスの切り替え

スマートフォン、タブレット、デスクトップで別々に確認してください。
レスポンシブ対応のサイトの場合、スマホエミュレーターではなく「実機で」試すのがほんま大事です。
エミュレーターと実機の挙動が違うことも珍しくありませんから。

スクリーンサイズとメディアクエリを徹底検証する

再現性のないバグで次に疑うべきは「ブレイクポイント周辺」です。

よくあるケースが、メディアクエリの境界線で予期しない動作が発生するパターン。
たとえば、max-width: 768pxmin-width: 769px が重複してたりすると、まさにその境界値で動作が変わります。

実際の確認方法としては:

  1. DevTools を開いて「デバイスモード」に切り替える
  2. ウィンドウ幅を1px ずつ変更しながら確認する
  3. メディアクエリが動作しているか「Styles」パネルで確認する

「Styles」パネルのメディアクエリのセクションをチェックすると、「このルールはメディアクエリで適用された」「こっちは適用されていない」がひと目でわかります。

僕の経験では、こういった「メディアクエリの干渉」が原因の再現性なしバグって、意外に多いんですよ。

CSSの継承と詳細度の「見えない競争」を追跡する

ここからが上級編ですね。
再現性のないバグの犯人が「親要素のスタイル」だったり「詳細度の競争」だったりするケースです。

詳細度の競争を見える化する

DevTools の「Styles」パネルを見ると、適用されているCSSと打ち消されているCSSが表示されます。
打ち消されているルール(打ち消し線が引かれてる)を見て、「あ、こっちが勝ってるのか」と判断できるわけです。

たとえば:

  • .container .button { color: blue; } (詳細度: 0, 2, 1)
  • .button { color: red; } (詳細度: 0, 1, 0)

この場合、前者の方が詳細度が高いので青色が勝ちます。
でも、「赤色で表示されてるんだけど…」という状況が起きると、「あ、parent から何か継承されてるのかな」と考えるわけです。

計算済みスタイルを確認する

DevTools の「Computed」タブを開くと、実際に要素に適用されている全スタイルが表示されます。
ここで確認すると「あ、このプロパティはこのファイルのこの行で定義されてるんだ」と、原因を特定できます。

特に z-indexmarginpadding の競争は、「見た目では同じに見えても実は別の値が適用されてる」みたいなことが起こるんで、ここで確認するのが必須です。

親要素の影響を切り分ける

再現性のないバグの中には「特定の親要素が存在した時だけバグる」というパターンもあります。

その場合は:

  1. 該当要素を DevTools で右クリック → 「Inspect」
  2. 親要素を一つずつ選んで「このクラスが原因かな」と仮説を立てる
  3. <style> タグで一時的に親要素のスタイルを display: none にしてみる

そうするとバグが消えるかどうかで、親要素が原因かどうかわかります。

まとめ