Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1228,12 +1228,31 @@ bootstrap-subset → theme-styles.styl の順で `/css/site.css` に連結する
- **ヘッダーの部品の寸法を本文のグリッドに従属させない。** 検索窓の幅を
サイドバー列に合わせれば揃うが、サイドバーが縦積みになる幅(1024px以下)で
その根拠が消える
- **ヘッダーの帯は追従(sticky)しない。** 64px の帯が全ページで本文の上に
常に乗ることになり、読んでいる面が狭くなる。写真をやめたぶん
`backdrop-filter` も要らなくなった
- **ヘッダーの帯は 1025px 以上で追従(sticky)する。1024px 以下では追従しない**
(#3220。#2877 の「追従しない」を PC だけ覆した)。読み進めてもロゴが左上に残り
「どのサイトを読んでいるか」が切り替わるたびに分かる、長いトップページで検索に
手が届く、が理由。他サイトは固定 3(Qiita 45px・note 65px・dev.to 56px)対
非固定 6(Zenn・はてな・Cloudflare・GitHub Blog・Stripe・Medium)で割れていて、
どちらが通り相場とも言えない
- **モバイルは追従しない。** 64px は 375×667 の画面の 10% で、記事の面を優先する
(Slack の議論でも PC の話に収束した)
- **境界は目次が追従し始める 1025px と同じ。** 新しい境界を足さず、PC の読者は
既に追従する部品のある画面を見ている
- **追従する帯は磨りガラス**(地を 90%、`backdrop-filter: blur(8px)`)。本文の上に
置かれた箱ではなく本文の一部として読ませる。**90% は帯の下にいちばん暗いもの
(コードブロック `#2b2b2b`)が来ても `ink-mute` が AA を保つ値**(5.15。85% では
4.65 で余裕が無い)。ぼかしの量は引き出しの背後(#2888)と同じ。`@supports` で
囲い、ぼかしが効かないブラウザでは不透明のまま——透けるだけだと文字の下に
本文が見えて読めない。線(1px)と影なしは変えない。下へ送ると隠れる型(Medium)は
JS が要り、送ると細くなる型は動きが増えるので採らない。2段組にして2段目だけ
固定する案は、帯が1段なので分ける相手が無い
- **帯を追従させると3箇所が連動する。** 目次の `top`(帯の下から 24px)と
`max-height`、目次のスクロールスパイの基準線(`sidebar.ejs`。帯の下辺 + 32px。
帯の `getBoundingClientRect().bottom` を読むので幅の分岐を持たない)、
`html { scroll-padding-top }`(目次のクリックとアンカーで見出しが帯の下に隠れない)
- **サイドバーの目次は追従する**(#2909。以前は「固定サイドバーを置かないのと
同じ理由」と書いていたが、そちらはトライアルで入れた)。目次は
読んでいる記事の中の移動手段で、帯のように全ページに常駐する部品ではない
読んでいる記事の中の移動手段で、帯と同じ幅で追従する
- **帯の中身は `.container` の内側に置く。** サイト名の左端がパンくず・本文と揃う。
下に開くパネル(ドロップダウン・検索のヒント)の位置の基準も `.header-bar` が持ち、
`top: 100%` が帯の下辺、`right: 0` が本文と同じ右端になる
Expand Down Expand Up @@ -1333,7 +1352,7 @@ bootstrap-subset → theme-styles.styl の順で `/css/site.css` に連結する
カーソルが乗っただけで本文全体がぼけるのは意図しない発火になる
- 開いているかは **`:has()`** で拾う。引き金(`:checked` / `:focus-within`)が
帯の中にあるので、兄弟結合子では帯の外の面まで届かない
- **`position: fixed` にしない。** ヘッダーは追従しないので、開いたまま送られると
- **`position: fixed` にしない。** 引き出しが出る幅ではヘッダーは追従しないので、開いたまま送られると
引き出しは一緒に上へ動くのにぼかしだけ残る。帯の下から 100vh 分を
絶対配置で敷く
- 出し入れは `display`。`visibility` では隠れている間も 100vh の箱が残り、
Expand Down
2 changes: 1 addition & 1 deletion source/specials/styleguide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ editable: true
| 576px | 検索窓が虫眼鏡だけになり、フォーカスされたときだけ帯を覆って広がる。一覧カードのサムネイルが文字の上に積む | [すべての記事](/articles/) |
| 768px | サイドバーの探索の枠が消える。2列で並べていた一覧が1列になる。コードと note が画面の端まで伸びる | [カテゴリ一覧](/categories/#categories) |
| 992px | ヘッダーのナビが帯から降りて引き出しに入る。フッターが4列から2列になる | [トップページ](/) |
| 1025px | 本文とサイドバーが縦に積む。サイドバーの統計とグラフは消え、目次は本文の上の折りたたみに移る | [記事ページ](/articles/20260804a/) |
| 1025px | 本文とサイドバーが縦に積む。サイドバーの統計とグラフは消え、目次は本文の上の折りたたみに移る。ヘッダーの帯は追従をやめて本文と一緒に送られる | [記事ページ](/articles/20260804a/) |

**中間の幅を作りません。** 段階を増やすと、どの幅で確かめた見た目なのかを追えなくなります。2列にするかどうかは列の内寸に中身が入るかで決めていて、たとえばカテゴリ一覧を「列の幅が足りたら自動で2列」にすると、幅 576px の画面でも1列 242px の2列になり、説明文とタグが入りません。列数は幅で決め打ちします。

Expand Down
40 changes: 34 additions & 6 deletions themes/future/css-src/theme-styles.styl
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,6 @@ Header and header elements
/* ヘッダーは1段・64px の帯 (#2877)。以前は 1500×360 の写真バナーの上に 80px の
中央タイトルを載せた 151px の塊で、全ページの先頭でそれだけ縦を使っていた。
縦に返した約90px のぶん、空いた横にサイト名・ナビ・検索を1行で並べる。
**追従(sticky)はしない。** 64px の帯が全ページで本文の上に常に乗ることになり、
読んでいる面が狭くなる。サイドバーの目次は追従する (#2909)。
影は持たない (#2747)。下辺の 1px の罫線が本文との境目を作る */
.site-header {
position: relative;
Expand All @@ -392,6 +390,36 @@ Header and header elements
/* 下に開くドロップダウンと検索のヒントパネルが本文の上に出る */
z-index: 999;
}
/* 1025px 以上では帯が追従する (#3220)。読み進めてもロゴが左上に残り、検索が
手の届く所にある。1024px 以下では追従しない——本文の面を優先する
(64px は 375×667 の画面の 10%)。境界は目次が追従し始める幅と同じで、
PC の読者は既に追従する部品のある画面を見ている。見た目は変えない
(白地・1px の線・影なし)ので、送っても浮いた箱にはならない。
scroll-padding は、目次のクリックや見出しのアンカーで見出しが帯の下に
隠れないためのもの。帯の線に見出しが接すると詰まって見えるので 16px 空ける
(目次のスクロールスパイの線は帯の下から 32px なので、着地した見出しは線の内側) */
@media (min-width: 1025px) {
.site-header {
position: sticky;
top: 0;
}
/* 追従する帯は磨りガラスにする。地を 90% にして下の本文をぼかして透かすと、
本文の上に置かれた箱ではなく本文の一部として読める。90% は帯の下にいちばん
暗いもの(コードブロック #2b2b2b)が来ても ink-mute が AA を保つ値
(4.5 に対して 5.15。85% では 4.65 で余裕が無い)。ぼかしの量は引き出しの
背後と同じ 8px。ぼかしが効かないブラウザでは不透明のまま——透けるだけだと
文字の下に本文が見えて読めない */
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
.site-header {
background: unquote('color-mix(in srgb, var(--surface-base) 90%, transparent)');
-webkit-backdrop-filter: blur(8px);
backdrop-filter: blur(8px);
}
}
html {
scroll-padding-top: header-height + 16px;
}
}
/* 帯の中身。左端はページ本文と同じ .container の内側に揃える。
下に開くパネルの位置の基準もここが持つ(top: 100% が帯の下辺になる) */
.header-bar {
Expand Down Expand Up @@ -3256,16 +3284,16 @@ ul.tag-list {
/* 左右の 4px は下の overflow-y: auto のため。スクロールコンテナになると
行のフォーカスの輪郭(2px + outline-offset 2px)が箱の縁で切られる */
padding: 0 4px;
/* スクロールに追従する (#2909)。帯は追従しないので、上端は画面の上から
少しだけ空ける。サイドバーが本文の下に落ちる幅(1024px以下)では
/* スクロールに追従する (#2909)。帯も追従する幅 (#3220) なので、上端は
帯の下から少しだけ空ける。サイドバーが本文の下に落ちる幅(1024px以下)では
目次自体を隠しているので、この指定は横並びのときだけ効く。

見出しが多い記事(h2〜h4 の中央値は10、最大62)では画面に収まらないので、
中でスクロールさせる。可視領域 800px で24項目まで入り、溢れるのは
全1,481本のうち68本(5%) */
position: sticky;
top: 24px;
max-height: unquote('calc(100vh - 48px)');
top: header-height + 24px;
max-height: unquote('calc(100vh - ' + (header-height + 48px) + ')');
overflow-y: auto;
}
/* 見出しにも行と同じ左パディングを与えて、文字の左端を項目と揃える。
Expand Down
13 changes: 9 additions & 4 deletions themes/future/layout/_partial/sidebar.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,19 @@
return a.compareDocumentPosition(b) & 4 ? -1 : 1;
});

// 画面の上から 32px の線を越えた見出しを「読み始めた」とみなす。
// 帯は追従しないので、送った後の画面の上端が基準になる。
// 帯の下辺から 32px の線を越えた見出しを「読み始めた」とみなす。
// 帯は 1025px 以上で追従する (#3220) ので、基準は画面の上端ではなく帯の下辺。
// 追従しない幅では送った帯が画面の外へ出るので、下辺は 0 で止める。
//
// **線は「見出しから次の見出しまでの最小距離」より浅くする。** 目次の行を
// クリックすると見出しが画面の上端(top 0)へ来るので、線が深いと次の見出しも
// 線より上に入り、次の節が現在地になってしまう。CSS の値から出した最小距離は
// h4 の直後に h4 が来る 46px(h3→h4 が 49px、h2→h3 が 72px)
var LINE = 32;
var header = document.querySelector('.site-header');
var line = function () {
var bottom = header ? header.getBoundingClientRect().bottom : 0;
return Math.max(0, bottom) + 32;
};
var current = null;
var queued = false;

Expand All @@ -164,7 +169,7 @@
// 文書順に並んでいるので、線より下に出たらそれ以降は全部下にある
var found = null;
for (var i = 0; i < headings.length; i++) {
if (headings[i].getBoundingClientRect().top >= LINE) break;
if (headings[i].getBoundingClientRect().top >= line()) break;
found = headings[i];
}
return found;
Expand Down
Loading