diff --git a/CLAUDE.md b/CLAUDE.md index 7501ed9d6dc..152b6ce14f9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -766,6 +766,25 @@ bootstrap-subset → theme-styles.styl の順で `/css/site.css` に連結する **767px 以下のコードと note**(`margin-inline: calc(50% - 50vw)` で画面端まで。 `.article-entry` 直下のものだけ #2568)。記事末の帯(#2874)は全幅だが、 中の `.container` が他ページと同じ左右を持つ + - **読み下す文章の1行は 45 字まで**(#3228。`article-measure` = `text-body × measure-chars`、 + `_variables.styl` が持つ)。本文列は 1200px 以上で 52.5字(819px)・61.2字(954px)になり、 + 和文の読み下しの帯(35〜45字)を超える。**列は動かさない**——`.container` と `col-md-9` は + 他ページと同じ枠(#3222)なので、**`.article-entry` の直下の文章の箱**(`p` / `ul` / `ol` / + `dl` / `blockquote` / `h1`〜`h6` / `hr` / `details` / `.note-container`)に `max-width` を置く。 + 入れ子(`li` の中の `p`、note の中のコード)は箱に従う。右に残る空きはサイドバーとの + 間隔に足され、本文の左端は動かない + - **コード・表・図・埋め込みは上限の外。列の幅を使う。** 読み下す対象ではなく、狭めると + 横スクロールと縮小が増えるだけ。全 7,898 のコードブロックで、横スクロールの要る割合は + 954px で 8.6%・819px で 14.6% だが、702px に狭めると 24.1% になる。画像は 6,065 枚の + 76% が実寸 702px 超。上の「はみ出してよいもの」は**列に対する**話で、こちらは + **列の中の文章の幅**なので別の規則 + - **`text-body` を幅で可変にする案は採らない。** 954px を 45 字に収めるには 21px が要り、 + 段の台帳(#2971)と「1つの要素のサイズは1箇所」に触るうえ、見出しの em の梯子・ + コード 13px との比・行間がすべて動く。読み下しの帯は字数の話なので、幅の側で解く + - 全 47,499 段落で、段落あたりの行数は 954px の 1.78 行から 45 字で 2.22 行になる + (1行で終わる段落 49.0% → 35.2%)。768〜1199px の読者が既に見ている行数(2.24〜2.27)と同じ + - 比較: Zenn 708px / 16px(44.3字)・Qiita 708px / 17px(41.6字)・はてなブログ 836px / + 17px(49.2字)。いずれも幅 1280〜1920px で本文の幅を変えない(2026-09 実測) - **時間の段は2つ+例外1つ**(#3222)。`_variables.styl` が持つ。**役で選ぶ** | 段 | 値 | 使うところ | diff --git a/source/specials/styleguide/index.md b/source/specials/styleguide/index.md index fd85063a1bf..983fd22f7f0 100644 --- a/source/specials/styleguide/index.md +++ b/source/specials/styleguide/index.md @@ -311,15 +311,24 @@ editable: true 左右の空きは全幅で 12px です。間隔の刻み(4px)の3つぶんで、幅の側だけ別の単位を持ちません。列の溝は 24px、本文とサイドバーの間は 44px(本文側 24px とサイドバー側 20px)で、どちらも同じ刻みに乗っています。 -| 画面幅 | ページの最大幅 | 本文列の内寸 | サイドバー | -| --- | --- | --- | --- | -| 〜575px | 画面いっぱい | 画面幅 − 24px | 本文の下 | -| 576〜767px | 540px | 516px | 本文の下 | -| 768〜991px | 720px | 696px | 本文の下 | -| 992〜1024px | 960px | 936px | 本文の下 | -| 1025〜1199px | 960px | 684px | 208px | -| 1200〜1399px | 1140px | 819px | 253px | -| 1400px〜 | 1320px | 954px | 298px | +| 画面幅 | ページの最大幅 | 本文列の内寸 | 文章の1行 | サイドバー | +| --- | --- | --- | --- | --- | +| 〜575px | 画面いっぱい | 画面幅 − 24px | 22.5字(375px) | 本文の下 | +| 576〜767px | 540px | 516px | 33.1字 | 本文の下 | +| 768〜991px | 720px | 696px | 44.6字 | 本文の下 | +| 992〜1024px | 960px | 936px | 45字(上限) | 本文の下 | +| 1025〜1199px | 960px | 684px | 43.8字 | 208px | +| 1200〜1399px | 1140px | 819px | 45字(上限) | 253px | +| 1400px〜 | 1320px | 954px | 45字(上限) | 298px | + +**読み下す文章の1行は 45 字までです。** 和文は1行が 35〜45 字を超えると、行末から次の行頭へ目が戻れなくなります。本文列は広い画面ほど広がるので、列の幅ではなく文章の箱の幅で止めます。上限は本文の文字の大きさに字数を掛けた値で、文字の大きさを変えれば追従します。 + +
+
+
+
+ +上限を持つのは段落・箇条書き・引用・見出し・note・折りたたみだけです。**コード・表・図・埋め込みは列の幅を使います。** これらは行として読み下す対象ではなく、狭めると横スクロールと縮小が増えるだけです。1400px 以上の画面ではコードの1行に 116 字入りますが、文章と同じ幅に合わせると 83 字まで落ち、横スクロールの要るブロックが 8.6% から 24.1% に増えます。右に残る空きはサイドバーとの間隔に足され、本文の左端は動きません。 **幅で切り替わる点は4つだけです。** どれも「その列に何が入るか」で決めていて、端末の呼び名では決めていません。 @@ -334,7 +343,7 @@ editable: true はみ出してよいものは3つあります。**記事の中の画像**は列いっぱいを上限に、縮めたいときは 520px と 360px の2段階から選びます(3段階目は置きません。狙った大きさがどちらとも違うなら、画像そのものを加工します)。**横に溢れる表**は受け皿の中で横スクロールし、ページ全体は横に動きません。**コードと note は、狭い画面でだけ画面の端まで伸びます。** 幅375pxでコードの1行に入る字数が 39.9 字から 45.0 字になり、横スクロールの要るブロックが 71.8% から 64.0% に下がります。文字の位置は段落の左端に揃うので、読者から見ると背景の帯だけが端まで伸びた形になります。本文末の帯(関連記事・We're hiring)も全幅ですが、中の左右は本文と同じ位置に揃えます。 -**幅の決まりは単位ではなく構造です。** 12px・24px・44px は間隔のスケールから借りているだけで、幅そのものが持つ決まりは「ページの種類で最大幅を変えない」「切り替わる点は4つ」「はみ出すのは画像・表・コードと note だけ」の3つです。値を覚える必要はなく、どの構造に当てはまるかだけを選びます。 +**幅の決まりは単位ではなく構造です。** 12px・24px・44px は間隔のスケールから借りているだけで、幅そのものが持つ決まりは「ページの種類で最大幅を変えない」「切り替わる点は4つ」「はみ出すのは画像・表・コードと note だけ」「読み下す文章の1行は 45 字まで」の4つです。値を覚える必要はなく、どの構造に当てはまるかだけを選びます。 ## 形と反応 diff --git a/themes/future/css-src/_variables.styl b/themes/future/css-src/_variables.styl index dc5f1dd7c8b..f27b15714c0 100644 --- a/themes/future/css-src/_variables.styl +++ b/themes/future/css-src/_variables.styl @@ -146,6 +146,13 @@ text-lead = 18px // サイト名・サイドバーの見出し text-title = 20px // 見出し・ロゴ・一覧カードの記事名 text-display = 24px // 大見出し(クラス無しの h2) +// 読み下す文章の1行の上限 (#3228)。和文は 35〜45字/行を超えると目が行頭に戻れない。 +// 本文列は 1200px 以上で 52.5字(819px)・61.2字(954px)に広がるので、 +// 読み下す段の値に字数を掛けて上限を置く。px を直接書かない——段を動かしたら +// 上限も同じ字数のまま追従する。対象は文章の箱だけで、コード・表・図は列の幅を使う +measure-chars = 45 +article-measure = text-body * measure-chars + // 間隔は4の倍数だけを使う。段を数え上げずに刻みだけを置くのは、 // 使う値が gap だけでも 2〜48px の13通りあり、上限を決める理由が無いため。 // 4px 刻みなら「隣の段」が必ず 4px 差になり、5px と 6px のような diff --git a/themes/future/css-src/theme-styles.styl b/themes/future/css-src/theme-styles.styl index 2606bbe556c..5ce804ba9bf 100644 --- a/themes/future/css-src/theme-styles.styl +++ b/themes/future/css-src/theme-styles.styl @@ -1514,6 +1514,29 @@ p { font-size: text-body; color: var(--ink-strong); } +/* 読み下す文章だけが1行の上限を持つ (#3228)。列(col-md-9)は他のページと同じ枠を + 共有するので動かさず(#3222)、本文の器の中で文章の箱の幅だけを止める。 + 右に残る空きはサイドバーとの間隔に足される。 + 当てるのは .article-entry の直下の箱で、中身(入れ子の li・note の中の p)は箱に従う。 + コード・表・図・埋め込み(figure.highlight / .scroll / img / figure / iframe / + .mermaid-svg)は読み下す対象ではなく、狭めると横スクロールと縮小が増えるだけなので + 列の幅のまま。見出しと hr を入れるのは、罫線を文章の右端でそろえるため */ +.article-entry > p, +.article-entry > ul, +.article-entry > ol, +.article-entry > dl, +.article-entry > blockquote, +.article-entry > h1, +.article-entry > h2, +.article-entry > h3, +.article-entry > h4, +.article-entry > h5, +.article-entry > h6, +.article-entry > hr, +.article-entry > details, +.article-entry > .note-container { + max-width: article-measure; +} /* details の summary は p / li と違って本文サイズの指定対象から漏れており、 body の 13px を継承して周囲(1.2em = 15.6px)より小さく表示されていた */ .article-entry summary { @@ -6606,6 +6629,28 @@ for n in sg-space-steps font-size: text-meta; } +/* 文章の1行の上限の見本 (#3228)。帯の長さも値も article-measure から出す。 + このページの段落自身が本物のルールで上限を受けているので、帯は段落の右端と揃う */ +.sg-measure { + margin: 0 0 24px; +} +.sg-measure-bar { + background: var(--brand-navy); + border-radius: radius-small; + height: 16px; + max-width: 100%; + width: article-measure; +} +.sg-measure-value { + color: var(--ink-mute); + font-family: font-mono; + font-size: text-meta; + margin-top: 4px; +} +.sg-measure-value::after { + content: unquote('"' + article-measure + ' = ' + text-body + ' × ' + measure-chars + '字"') +} + /* 下線の位置の見本。値は _variables.styl から借りる。ここに px を書くと 決める場所が2つになる(文字の大きさの見本と同じ流儀)*/ .sg-underline-offset::after {