概要
- 開発者が陥りやすい HTML/CSS、Unicode、浮動小数点、時間 に関する落とし穴の要約
- 直感に反する挙動 や 誤解 しやすい仕様を中心に整理
- バグの原因 となりやすいポイントを明確化
- 各分野ごと に代表的なトラップを箇条書きで説明
- 対策や回避策も簡潔に記載
HTML・CSSの落とし穴
- flexboxやgrid内 では、デフォルトで min-width: auto が設定され、内容に応じて最小幅が決まる
- min-width: 0 を明示的に指定することで、flex-shrinkやoverflow等の他プロパティが正常に動作
- width: auto と height: auto の挙動は異なる
- 横方向は親要素の空間を埋めるが、縦方向は内容に合わせて伸びる
- inline要素やinline-block要素、float要素 ではwidth: autoは拡張しない
- margin: 0 auto は水平方向中央寄せ
- margin: auto 0 は通常上下中央寄せにならない
- flex-direction: column のflexboxでのみmargin: auto 0が垂直中央寄せとなる
- マージンの折り畳み(margin collapse) は垂直方向のみ発生
- BFC(Block Formatting Context)やborder/padding指定で回避可能
- display: flow-root や overflow: hidden 等でBFCを作成
- 親がfloat子要素のみ含む場合、親の高さが0になる
- BFCで解決可能
- スタッキングコンテキスト の発生条件
- transform, filter, opacity等の特殊効果
- position: fixed/sticky、z-index指定+position: absolute/relative
- isolation: isolate
- z-indexはスタッキングコンテキストをまたいで効かない
- position: absolute/fixedは最も近いpositioned ancestor基準
- 100vh問題
- モバイルブラウザのアドレスバー表示/非表示で高さが変動
- 100dvh が推奨値
- position: absolute は親要素ではなく最も近いpositioned ancestor基準
- display: flexやgridの親下でfloatは無効
- 親のwidth/height未定義時、%指定のwidth/heightは効かない
- display: inline はwidth/heightやmargin-top/bottom無効
- HTMLの空白・改行はデフォルトで1つの空白にまとめられる
- <pre> で回避可能だが、先頭・末尾の空白は特殊挙動
- inline-block要素間の空白 はスペースとして描画(flexboxやgridでは発生しない)
- text-alignはインライン要素のみ整列
- width/heightはデフォルトでpadding/borderを含まない
- box-sizing: border-box で全体幅に含める
- 画像の遅延読み込みによるCumulative Layout Shift
- <img>にwidth/height属性指定 推奨
- ファイルダウンロードリクエストはChrome DevToolsで見えない
- chrome://net-export/ で確認
Unicode・テキスト処理の落とし穴
- コードポイント(rune)とグラフェームクラスタ の違い
- GUI上の「1文字」はグラフェームクラスタ
- 絵文字は複数コードポイントから成ることも
- UTF-8は1~4バイト、UTF-16は2バイト単位
- 文字数・インデックスの扱いは言語ごとに異なる
- Rust: UTF-8、s.len()はバイト数、s.chars().count()はコードポイント数
- Go: 文字列はバイト列、インデックスもバイト単位
- Java/C#/JS: UTF-16、長さ・インデックスは2バイト単位
- Python: len(s)はコードポイント数、インデックスもコードポイント単位
- C++: std::stringはエンコーディング非依存、バイト単位
- グラフェームクラスタ単位の長さ・インデックス取得は標準で不可
- BOM(Byte Order Mark) の扱い
- 一部ソフトで非対応
- バイナリ→文字列変換時の不正箇所はU+FFFD(�)に置換
- 正規化・類似文字 問題
- 例:éはU+00E9またはU+0065 U+0301
- ゼロ幅・不可視文字 の混入
- 改行コードの違い
- Windows: CRLF (\r\n)、Linux/Mac: LF (\n)
- 漢字統合(Han unification) によるフォント依存表示
- 多言語対応ではフォント選択が重要
浮動小数点の落とし穴
- NaNは何とも等しくない(NaN == NaNはfalse)
- 計算にNaNが混入すると全体がNaN化
- +Infと-InfはNaNと別物
- -0.0と+0.0は区別される
- 1.0 / +0.0は+Inf、1.0 / -0.0は-Inf
- JSON標準はNaN/Inf非対応
- JS: nullに変換
- Python: allow_nan=Falseでエラー
- Go: エラー
- 浮動小数点の比較は誤差を考慮
- abs(a - b) < 0.00001等で比較
- JavaScriptの安全な整数範囲
- 2^53-1までが安全、それ以上はBigInt推奨
- 大きな整数をJSONで扱う場合は文字列化
- 結合法則・分配法則が厳密には成立しない
- 並列計算で非決定的結果になることも
- 除算は乗算より遅い
- 逆数を先に計算して乗算で高速化
- ハードウェアによる差異
- FMA(fused multiply-add)やサブノーマル数
- 丸めモード(RNTE, RTZ等)、CPU/GPUでの挙動違い
- X86の80bit FPUは非推奨
- 精度向上の工夫
- 計算グラフの浅さ、FMA活用、中間値の絶対値管理
時間処理の落とし穴
- Unixタイムスタンプはうるう秒を考慮しない
- うるう秒付近で「引き伸ばし」や「圧縮」が発生
- タイムゾーン・DST(夏時間)の影響
- タイムスタンプ保存+UIで人間可読化が推奨
- サーバーはUTC設定が望ましい
- 分散システムでタイムゾーン不一致は厄介
- システム時刻とハードウェア時刻の違い
- タイムゾーン変更時はDB再起動等が必要な場合あり
- NTP同期等による時刻の「巻き戻り」
- 時間の一意性・単調性に注意
上記以外にも、各分野で 直感に反する仕様や落とし穴 が多く存在。 実装前に仕様書や公式ドキュメントの確認 が重要。