0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「横溢れ 0」を信じたら 44 組中 32 組が崩れていた——幅の両側と操作後を測る格子

0
Posted at

自社サイトの見た目の検査は、1280px と 375px で頁を開き、横に溢れていないかを数えていた。どの頁も 0。ところが 375px でメニューを開くと、頁が横に 126px 伸び、ロゴが 101px 下へ落ちていた。直した 3 日後に、直す前・1 回目に直した後・再点検時点の 3 つの版を 4 頁 × 11 幅 × 操作後の状態で測り直し、見つかった残りを直してもう一度測った記録です。

幅の帯 × 状態。直す前と直した後

この記事の位置づけ(2026-09-26 追記)

  • 既に知られていること: innerWidth はスクロールバーを含み、除くなら clientWidth を使うこと(MDN)。
  • この記事で新しく示すこと: 2 幅の閉じた状態だけの検査が見落とした 32 組を、幅の両側と操作後の状態の格子で見つけた数。
  • 当てはまる範囲: 当方のサイト 4 頁・Chromium だけ。スクロールバーのある窓では 15px 以下の溢れを見落とします。
  • 言葉: 本文の「器」=点検や処理のための自作スクリプトのことです。

数字の元データと再現の手順は、検証の記録(Lab)にまとめています。

先に結論

  1. 直す前の版は、頁と幅の組 44 のうち 32 組で横に溢れていた。検査が見ていた 2 つの幅(閉じた状態の 375 と 1280)では、溢れは 1 組も出ない。
  2. 32 組のうち 20 組は、メニューを開かなくても溢れていた。場所は 601px と 901〜1141px=ブレークポイントの上側の帯。見落としの主因は「状態」より「幅」だった。
  3. 375px のメニューを開いたときの +126px(トップ)は、条件なしで書いた flex-wrap: nowrap を 1 行外すと 0、戻すと +126 になった。ただし外して戻したのはこの 1 組だけ。
  4. 溢れ量だけ見ていると、grid の列が 0px に潰れた頁を通してしまう。列幅 8px 未満を赤にすると、溢れ 0 の組で潰れた列が見つかった。

何が起きていたか

メニューを開いた状態でヘッダの箱 .site-header .wrap の計算値を見ると、flex-wrap が nowrap(折り返さずに 1 行へ並べる)のままだった。

base.css にはこの選択子で flex-wrap を指定する規則が 5 つあった。600px 以下と 900px 以下では wrap を指定している。それなのに効いていたのは、ファイルの後ろの方にある条件なしの 1 行だった。

/* 09-20 に足した行(メディアクエリの外・当時 1,763 行中 1,505 行目)。ヘッダを 1 段 72px にする */
.site-header .wrap { flex-wrap: nowrap; gap: 28px; min-height: 72px; padding-top: 0; padding-bottom: 0; }

詳細度が同じなら後ろが勝つ。PC の見本に合わせて後ろの方に足した 1 行が、前にあった 900px 以下・600px 以下の wrap を上書きしていた。

原因は「外して戻るか」で確かめる

同じ選択子が何回書かれているか(直す前 9 回・直した後 12 回)は、書き方が散らかっているという補助にはなるが、どれが勝っているかは教えてくれない。そこで CSSOM から該当の規則を並べ、今当たる最後の 1 つだけを外した。

// iframe の中の document で。rule は .site-header .wrap を持つ CSSStyleRule
const pr = rule.style.getPropertyPriority('flex-wrap');
rule.style.removeProperty('flex-wrap');          // 外す → 測る
rule.style.setProperty('flex-wrap', 'nowrap', pr); // 戻す → 測る
横の溢れ ロゴの位置
そのまま +126px 101px 下
その 1 行だけ外す 0 上端
戻す +126px 101px 下

各段を 2 回ずつ測り、同じ値だった。外すと直り、戻すとまた崩れるので、原因はこの 1 行と言える。

勝っていた宣言を 1 つ外すと戻った

格子の組み方

測る器はブラウザの console に貼る JavaScript 1 本。同一オリジンの iframe を置き、その幅を変えて頁を読み直すと、iframe の幅がそのまま viewport になる。メディアクエリも iframe の幅で効く。

const f = document.createElement('iframe');
f.style.cssText = 'position:fixed;left:0;top:0;height:900px;border:0';
document.body.appendChild(f);
for (const w of [375, 390, 600, 601, 768, 900, 901, 1024, 1140, 1141, 1280]) {
  f.style.width = w + 'px';
  await new Promise((r) => { f.onload = r; f.src = '/works/?w=' + w; });
  await f.contentDocument.fonts.ready;
  await new Promise((r) => setTimeout(r, 600));
  const d = f.contentDocument, win = f.contentWindow;
  console.log(w, Math.max(0, d.documentElement.scrollWidth - win.innerWidth));
}

実際の器は、これに頁ごとの状態(メニューを開く・部門の一覧を開く・本文の details を開く・一覧を絞り込む)と、列の潰れの判定を足している。

  • 幅は両側を入れる: 600/601、900/901、1140/1141。閉じた状態の赤 20 組は、すべて 601px と 901〜1141px=ブレークポイントの上側の帯にあった。
  • 待ちは 600ms: クリック直後はアニメーションの途中の値が出る。
  • スクロールバーの分は見えない: innerWidth はスクロールバー込みの幅なので、バーのある窓(Windows の Chromium で約 15px)では 15px 以下の溢れが 0 になる。赤の数は下限(2026-09-26 追記・外部精査の指摘)。
  • 列の潰れ: 表示中の grid 要素で、getComputedStyle(el).gridTemplateColumns の値のどれかが 8px 未満なら赤。8px はこのサイトで今回決めた線で、一般の基準ではない。

4 つの版を並べる

頁 × 幅の組 直す前(09-21 12:23) 1 回目の後(同日 14:28) 再点検時点(09-24) 2 回目の後(09-24)
測った組 44 44 44 126(9 頁 × 14 幅)
横に溢れた組 32 3 2 0
うちメニューを開いたときだけ 12 0 0 0
grid の列が潰れた組 11 10 4 0

1 回目に直した後も、トップの 901px で +108、1141px で +12 が残っていた。記事を書くために再点検すると、1141px の +12 と、点検修理の頁の 901〜1141px で 2 列目が 0px の箱がまだあった。同じ日に「列 0px の欠陥も直し」と書いた commit があったが、この頁だけ箱の型の切り替えが漏れていた。

この 2 つは同じ日に直した。ヘッダを詰める幅の上端を 1140px から 1180px に広げ(Works の頁は 1160px で溢れが 0 になった)、点検修理の頁の箱をほかの Works の頁と同じ縦並びにした。直した後は 9 頁 × 14 幅の 126 組(状態込みで 320 セル)で、溢れも列の潰れも 0。本番でも 1141px と 1181px を含む境界の 6 か所で溢れが 0 だった。

持ち帰り

  • ブレークポイントが b なら、b−1・b・b+1 を測る。 今回の閉じた状態の赤は、全部が 601px と 901〜1141px=ブレークポイントの上側の帯にあった。代表の幅(375 と 1280)だけでは 1 組も見えない。
  • 閉じた状態と、操作した後を両方測る。 メニューを開いたときだけ赤の組が 12 あった。
  • 崩れの原因は、勝っている宣言を 1 つ外して直るか、戻して崩れるかで確かめる。 出現回数は勝ち負けを決めない。
  • 溢れ量に加えて、列が 0 に近く潰れていないかも数える。 数える単位(頁 × 幅の組)は溢れと揃える。

この記録で言えないこと

  • 測ったのは Chromium(Chrome 152)だけ。Safari・Firefox・実機は見ていない。
  • 1 サイトだけ。幅の間(例 1000px)は測っていない。
  • 本番 build ではなく astro dev で測った。当時の記録(+127)と 1px ずれ、原因は切り分けていない。本番で測ったのは境界の 6 か所だけ。
  • 外して戻したのは 375px のメニュー開の 1 組だけ。閉じた状態で溢れた 20 組の原因は、同じ形では確かめていない。
  • 文字のコントラストはこの格子では測っていない(既存の別の検査で見ている)。

AI の利用について

格子の器・外して戻す器・集計・図・本文の下書きは Claude Code で作りました。図と表の数字は器が書き出した JSON から写しています。

関連


この記事は Zenn にも同じ内容を掲載しています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?