diff --git a/CLAUDE.md b/CLAUDE.md index 34c984dab6b..e97542d28d7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -728,6 +728,54 @@ bootstrap-subset → theme-styles.styl の順で `/css/site.css` に連結する 生まれない。以前は 2 / 3 / 5 / 6 / 10 / 14 / 25px が混ざっており、多くは 「円の直径の半分」のようにその場で計算した値で、隣の部品と揃える理由が無いまま 1px ずつ違っていた +- **ページの最大幅は種類で変えない。幅で切り替わる点は4つだけ**(#3222)。 + 記事・一覧・トップ・特設はすべて同じ `.container`(540 / 720 / 960 / 1140 / 1320px)に + 入る。左右の空きは全幅で 12px、列の溝は 24px、本文とサイドバーの間は 44px + (本文側 24px + サイドバー側 20px)で、**いずれも間隔の 4px 刻みの上にある** + (幅の側だけ別の単位を持たない) + - 切り替わるのは **576 / 768 / 992 / 1025px** の4つ。どれも「その列に何が入るか」で + 決まる。576px = 検索窓が虫眼鏡だけになる・一覧カードのサムネが縦積み、 + 768px = サイドバーの探索の枠が消える・2列の一覧が1列・コードと note が全幅、 + 992px = ナビが引き出しに入る・フッターが4列から2列、 + 1025px = 本文とサイドバーが縦積み・サイドバーの統計とグラフが消える・ + 目次がモバイルの折りたたみへ + - **`max-width` の側は 767 / 991 / 1024、`min-width` の側は 576 / 768 / 992 / 1025 で書く。** + 同じ境界を 767 と 768 の両方で書くと、768px ちょうどで両側が同時に当たる + (サイドバーの枠だけ 768px になっていて、2列化と重なっていた #3222) + - **992px と 1025px は別の境界で、片方に寄せない。** 992px は帯に何本並ぶかで、 + 1025px は2列にしたときの列の内寸で決まる(1025px 未満で2列にすると本文 684px・ + サイドバー 208px より狭くなる #2044)。**幅で囲む規則はどちらの境界に属するかを + 決めてから書く**——ドロップダウンを畳む規則が 1025px 側に付いていて、 + 992〜1024px では帯にナビが並ぶのに効かず、開いたパネルが残っていた(#3222) + - **中間の幅を作らない。** 2列にするかは列の内寸に中身が入るかで決めるが、 + `column-width` で自動に落とすと幅 576px の端末でも2列(1列 242px)になる。 + **列数は幅で決め打ちする**(#3180 と同じ判断) + - はみ出してよいのは3つだけ。**記事の中の画像**(列いっぱいを上限に、`img-width-middle` + 520px と `img-width-small` 360px の2段)・**横に溢れる表**(`.scroll` の中で横スクロール)・ + **767px 以下のコードと note**(`margin-inline: calc(50% - 50vw)` で画面端まで。 + `.article-entry` 直下のものだけ #2568)。記事末の帯(#2874)は全幅だが、 + 中の `.container` が他ページと同じ左右を持つ +- **時間の段は2つ+例外1つ**(#3222)。`_variables.styl` が持つ。**役で選ぶ** + + | 段 | 値 | 使うところ | + | --- | --- | --- | + | `hover-speed` | 0.05s | 反応。色・面・下線が変わるところすべて | + | `state-speed` | 0.18s | 状態の変化。タブの切り替え・ドロップダウンと引き出しの開閉・検索窓の伸縮・折りたたみの開閉 | + | `footer-underline-speed` | 0.25s | 例外。フッターのリンクの下線(#2839) | + + - **状態の変化の側も1つだけ。** 以前は 0.12 / 0.15 / 0.18 / 0.2s が部品ごとに散っていて、 + 役が4つあるのではなく別々に決めた値が残っていただけだった。0.02〜0.05s の差は + 見分けられない(#2534 の「見分けの付かない差に2つの役を割り当てない」と同じ理屈) + - **同じ操作の中で2つの段を混ぜない。** ヘッダーのカレットの回転が `hover-speed`、 + 指しているパネル本体が `state-speed` で、同じ「開く」が2つの速さで動いていた(#3222) + - **イージングは触らない**(#2693)。体感を決めているのは秒数だけ + - **`prefers-reduced-motion: reduce` では状態の変化を止め、反応は残す。** 開閉も + 切り替えも結果だけを出す(`transition: none`)。0.05秒の色・面・下線は動きではなく + 押せることの合図なので止めない(#2686 と同じ線引き) + - **打ち消しは対象と同じ詳細度で、対象より後ろに置く**(メディアクエリは詳細度を + 上げない)。基底と開いた側の両方に `transition` があるなら両方を打ち消す + - **例外はドロップダウンと検索ヒントの `visibility 0s 0.3s`。** あれは動きではなく、 + 消えるまでに click を届かせるための待ち時間(Safari 対策)なので残す - **サムネイルの寸法は5つしかない。新しい値を作らず、器の形で選ぶ**(#2790)。 いずれも `object-fit: cover` で切り抜き、角丸は `radius-small`。サムネの実寸は 幅300px・高さがばらばら(比 1.0〜3.2)なので、寸法はこちら側の枠が決める @@ -1531,7 +1579,7 @@ bootstrap-subset → theme-styles.styl の順で `/css/site.css` に連結する GA4 の値が 100 単位に丸められていて(全1,499件が100の倍数)、窓の中の合計では 同点が構造的に出ていたため(Business と Culture が 10,000PV でちょうど上限の線に 並んだ)。経過年で割ると値がばらけるので、実測で同点は0件になった(#3038) - - **768px 以下では3枠とも消える**(`display: none`)。サイドバーは本文の下に落ちるので、 + - **767px 以下では3枠とも消える**(`display: none`)。サイドバーは本文の下に落ちるので、 一覧25本とページャの後ろに出しても読者は辿り着かない(目次を `.toc-mobile` に 移したのと同じ理由 #2452)。モバイルの行き先はヘッダーの引き出しが持つ - 連載をここに入れたのは、646本(全記事の44%)を束ねる軸だから(#2892)。 diff --git a/source/specials/styleguide/index.md b/source/specials/styleguide/index.md index 74e5690f287..e50da25bbec 100644 --- a/source/specials/styleguide/index.md +++ b/source/specials/styleguide/index.md @@ -305,6 +305,37 @@ editable: true 段階を数え上げないのは、使う値が並びの間隔だけでも 4〜48px と幅広く、どこで打ち切る理由も無いからです。刻みを4pxに揃えておけば隣の段階が必ず 4px 差になり、5px と 6px のように**見分けの付かない差**が生まれません。色を3段階に絞ったのと狙いは同じで、迷う余地を減らすためです。 +## 幅 + +**ページの最大幅は種類で変えません。** 記事も一覧もトップも同じ枠に入ります。読む対象が変わってもページの左端と右端が動かないので、どのページでも同じ場所を見に行けます。 + +左右の空きは全幅で 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 | + +**幅で切り替わる点は4つだけです。** どれも「その列に何が入るか」で決めていて、端末の呼び名では決めていません。 + +| 幅 | 狭い側で変わるもの | 実物 | +| --- | --- | --- | +| 576px | 検索窓が虫眼鏡だけになり、フォーカスされたときだけ帯を覆って広がる。一覧カードのサムネイルが文字の上に積む | [すべての記事](/articles/) | +| 768px | サイドバーの探索の枠が消える。2列で並べていた一覧が1列になる。コードと note が画面の端まで伸びる | [カテゴリ一覧](/categories/#categories) | +| 992px | ヘッダーのナビが帯から降りて引き出しに入る。フッターが4列から2列になる | [トップページ](/) | +| 1025px | 本文とサイドバーが縦に積む。サイドバーの統計とグラフは消え、目次は本文の上の折りたたみに移る | [記事ページ](/articles/20260804a/) | + +**中間の幅を作りません。** 段階を増やすと、どの幅で確かめた見た目なのかを追えなくなります。2列にするかどうかは列の内寸に中身が入るかで決めていて、たとえばカテゴリ一覧を「列の幅が足りたら自動で2列」にすると、幅 576px の画面でも1列 242px の2列になり、説明文とタグが入りません。列数は幅で決め打ちします。 + +はみ出してよいものは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つです。値を覚える必要はなく、どの構造に当てはまるかだけを選びます。 + ## 形と反応 ### 角丸は3段階 @@ -327,9 +358,7 @@ editable: true ### hover は1部品1反応 -同じ「押せる」の合図なので、速さは 0.05 秒の1つだけです。反応は待たせるものではないので短い側に寄せています。0.1 秒だと変化が半分進むのに 29ms かかり、カーソルを乗せて 20ms の時点でまだ3割しか動いていません。0.05 秒なら 15ms で7割動くので、ほぼ即時に見えます。 - -イージングは触りません。体感を決めているのは秒数だけで、20ms 時点の進捗は ease 30% 対 ease-out 31% とほぼ同じでした。 +同じ「押せる」の合図なので、速さも1つだけです。秒数の決まりは下の「時間」がまとめて持ちます。 反応は入れ子のうち**外側だけ**が返します。 @@ -358,7 +387,7 @@ editable: true ヘッダーの帯の中だけは、下線も背景も動かさず文字色を1段階濃くします(帯から下がるドロップダウンの行は背景が変わります)。 -フッターのリンクだけは例外で、下線が左から 0.25 秒で伸びます。読者がわざわざ辿り着いた先なので動きを持たせても認知負荷にならない、という判断です。**開閉・展開は反応ではなく状態の変化**なので、別の時間を持ちます。タブの切り替え、ドロップダウンと引き出しの開閉、検索窓の拡張、折りたたみの開閉がこれで、いずれも hover より長い側(0.12〜0.2 秒)に置きます。変わったことが読み取れるまで動きが続く必要があるからです。 +フッターのリンクだけは例外で、下線が左から伸びます。**開閉・展開は反応ではなく状態の変化**なので、別の時間を持ちます。タブの切り替え、ドロップダウンと引き出しの開閉、検索窓の拡張、折りたたみの開閉がこれです。 ### フォーカスリング @@ -368,6 +397,25 @@ editable: true 暗い背景(フッターとヘッダーの帯)ではネイビーが見えないので、`on-dark-strong` に替えます。白背景の入力欄のように背景が明るいまま暗い場所に置かれる部品は、色ではなく `outline-offset: -2px` で内側に逃がします。 +## 時間 + +役割は2つです。**押せることの合図(反応)と、開いたり切り替わったりしたこと(状態の変化)**で、前者は待たせるものではないので短い側、後者は変わったと読み取れるまで続く必要があるので長い側に置きます。 + +| 役割 | 時間 | 使うところ | +| --- | --- | --- | +| 反応 | 0.05 秒 | 色・面・下線が変わるところすべて | +| 状態の変化 | 0.18 秒 | タブの切り替え、ドロップダウンと引き出しの開閉、検索窓の拡張、折りたたみの開閉 | + +**どちらの役割も値は1つです。** 反応が 0.05 秒なのは、0.1 秒だと変化が半分進むのに 29ms かかり、カーソルを乗せて 20ms の時点でまだ3割しか動いていないからです。0.05 秒なら 15ms で7割動くので、ほぼ即時に見えます。0 にはしません。タグのチップのように面の広いところでは、ハードカットだと切り替わる瞬間が硬く出ます。 + +**イージングは触りません。** 体感を決めているのは秒数だけで、20ms 時点の進捗は ease 30% 対 ease-out 31% とほぼ同じでした。 + +フッターのリンクの下線だけは例外で、左から 0.25 秒で伸びます。読者がわざわざ辿り着いた先なので動きを持たせても認知負荷にならない、という判断です。**この1つだけをスケールの外に置きます。** 反応の側に混ぜると「押せることの合図は1つの速さ」が言えなくなり、状態の変化の側に混ぜると開閉と同じ役割に見えます。 + +**位置や大きさが動くのは、開いたことを示す部品だけです。** 折りたたみの三角・ドロップダウンの矢印・引き出しの三本線が回り、検索窓が横に伸びます。読む対象そのもの(記事のカードや行、本文)は動きません。反応で動くのは下線と背景だけです。 + +**動きを減らす設定では、状態の変化を瞬時にします。** 開閉も切り替えも結果だけが出て、途中の動きは出ません。反応の 0.05 秒は止めません。あれは動きではなく、押せることの合図そのものだからです。 + ## 状態 部品が「今どうなっているか」は、**新しい色を足さずに、すでにあるスケールの中で1つだけ動かして**表します。動かすのは太さか面のどちらか一方で、両方は動かしません。 diff --git a/themes/future/css-src/_variables.styl b/themes/future/css-src/_variables.styl index 708042997ef..dc5f1dd7c8b 100644 --- a/themes/future/css-src/_variables.styl +++ b/themes/future/css-src/_variables.styl @@ -307,9 +307,8 @@ img-width-small = 360px // hover / focus の反応の速さ。1つだけ置く(#2686)。 // 以前は 0.1 / 0.15 / 0.2 / 0.3 秒が部品ごとに散っていて、同じ「押せる」の // 合図なのに速さが違っていた。反応は待たせるものではないので短い側に寄せる。 -// 対象は色・面・下線・カードの持ち上がりまで。開閉のアニメーション -// (details の高さ・三角の回転)と検索欄の伸縮は状態の変化であって -// 反応ではないので、それぞれの時間を持つ。 +// 対象は色・面・下線。開閉のアニメーション(details の高さ・三角の回転)と +// 検索欄の伸縮は状態の変化であって反応ではないので、state-speed が持つ。 // // 0.1s では「もっさり」と感じられたので詰めた(#2693)。0.1s だと変化が半分 // 進むのに 29ms 掛かり、カーソルを乗せて 20ms 経った時点でまだ3割しか動いて @@ -336,32 +335,14 @@ footer-underline-speed = 0.25s // 間隔の 4px 刻みとは別の系統なので、space-step からは導かない link-underline-offset = 2px -// タブの切り替え(#2728)。反応ではなく状態の変化なので hover-speed とは別に持つ。 -// details の開閉(0.18s)に合わせた。中身が入れ替わったことが分かる程度で、 -// 待たされない長さ -tab-speed = 0.18s +// 状態が変わったことを見せる速さ。反応(hover-speed)とは役が違うので別に持つが、 +// **状態の変化の側も1つだけ**。タブの切り替え・ドロップダウンと引き出しの開閉・ +// 検索窓の伸縮・折りたたみの開閉が対象で、中身が入れ替わったことが分かる程度で +// 待たされない長さ。 +// 以前は 0.12 / 0.15 / 0.18 / 0.2s が部品ごとに散っていた。役が4つあるのではなく +// 別々に決めた値が残っていただけで、0.02〜0.05s の差は見分けられない +state-speed = 0.18s -// Layout -block-margin = 50px -article-padding = 20px -mobile-nav-width = 280px -main-column = 9 -sidebar-column = 3 - -if sidebar and sidebar isnt bottom - _sidebar-column = sidebar-column -else - _sidebar-column = 0 - -// Grids -column-width = 80px -gutter-width = 20px -columns = main-column + _sidebar-column - -// Media queries -mq-mobile = "screen and (max-width: 479px)" -mq-tablet = "screen and (min-width: 480px) and (max-width: 767px)" -mq-normal = "screen and (min-width: 768px)" // 色の付いた地の上に置くインラインコードの背景を返す (#2487)。 // 「地より一段濃い同じ色」という関係を1箇所で定義し、note の4色でも // テーブルヘッダでも同じ規則が効くようにする。個別に値を決めていた頃は diff --git a/themes/future/css-src/theme-styles.styl b/themes/future/css-src/theme-styles.styl index 0e6b80c6472..ef304583aa1 100644 --- a/themes/future/css-src/theme-styles.styl +++ b/themes/future/css-src/theme-styles.styl @@ -548,7 +548,14 @@ Header and header elements } .header-nav-caret { color: var(--ink-faint); - transition: transform hover-speed ease; + /* パネル本体と同じ state-speed。回転は反応ではなく開いたことの合図 */ + transition: transform state-speed ease; +} +/* 動きを減らす設定では回さずに向きだけ変える。パネルの開閉そのものは残る */ +@media (prefers-reduced-motion: reduce) { + .header-nav-caret { + transition: none; + } } .header-nav-item:hover .header-nav-caret, .header-nav-disclosure[open] .header-nav-caret { @@ -568,7 +575,7 @@ Header and header elements border-radius: card-radius; visibility: hidden; opacity: 0; - transition: opacity 0.12s ease, visibility 0s 0.3s; + transition: opacity state-speed ease, visibility 0s 0.3s; } /* カテゴリは18件あるので2列にする。列数は数えず**列幅の下限**で決める。 最長の行は DataEngineering の101px(13px・Noto Sans CJK の実測)+ @@ -598,14 +605,28 @@ Header and header elements .header-nav-disclosure[open] ~ .header-dropdown { visibility: visible; opacity: 1; - transition: opacity 0.12s ease; + transition: opacity state-speed ease; +} +/* 動きを減らす設定では送らずに出し入れする。閉じるときの visibility の遅延は + 残す。あれは動きではなく、消えるまでに click を届かせるための待ち時間 */ +@media (prefers-reduced-motion: reduce) { + .header-dropdown { + transition: opacity 0s, visibility 0s 0.3s; + } + .header-nav-item:hover .header-dropdown, + .header-nav-disclosure[open] ~ .header-dropdown { + transition: none; + } } /* 開いたままカーソルもフォーカスも離れたら畳んで見せる(open 属性は残る)。 これが無いと、別の引き金にカーソルを乗せたときに2枚が同じ位置で重なる。 引き金へ戻れば また出るので、開いた読者の意図は保たれる。 - **幅で囲むのは、引き出し(1024px 以下)ではパネルを常時開いて並べているため。** - 囲まないとこの規則の詳細度が勝ち、引き出しで引き金を押した瞬間に消える */ -@media (min-width: 1025px) { + **幅で囲むのは、引き出し(991px 以下)ではパネルを常時開いて並べているため。** + 囲まないとこの規則の詳細度が勝ち、引き出しで引き金を押した瞬間に消える。 + 境界はナビが帯から降りる幅(992px)に合わせる。サイドバーの縦積み(1025px)に + 合わせると、992〜1024px は帯にナビが並ぶのにこの規則が効かず、 + 押して開いたパネルが離れても残る */ +@media (min-width: 992px) { .header-nav-item:not(:hover):not(:focus-within) .header-nav-disclosure[open] ~ .header-dropdown { visibility: hidden; opacity: 0; @@ -815,9 +836,8 @@ Header and header elements /* 線なのでピルにする。角丸の段の3つ目 */ border-radius: 999px; background: var(--ink-mute); - /* 開閉は反応ではなく状態の変化なので、hover-speed ではなくこちらの段 - (details の開閉・タブの切り替えと同じ 0.18s) */ - transition: transform tab-speed ease, opacity tab-speed ease; + /* 開閉は反応ではなく状態の変化なので、hover-speed ではなく state-speed */ + transition: transform state-speed ease, opacity state-speed ease; } /* 上下の線を中央へ寄せてから回す。6px は線の高さ2pxと間隔4pxの和で、 間隔の段として選んだ値ではない。角度は参照実装(リクルートサイト)と @@ -828,6 +848,12 @@ Header and header elements .header-drawer-input:checked + .header-drawer-toggle .header-drawer-bar:nth-child(2) { opacity: 0; } + /* 動きを減らす設定では回さずに ✕ の形へ切り替える */ + @media (prefers-reduced-motion: reduce) { + .header-drawer-bar { + transition: none; + } + } .header-drawer-input:checked + .header-drawer-toggle .header-drawer-bar:nth-child(3) { transform: translateY(-6px) rotate(135deg); } @@ -1611,7 +1637,13 @@ p { border-left: 6px solid var(--ink-faint); border-top: 5px solid transparent; border-bottom: 5px solid transparent; - transition: transform 0.2s ease; + transition: transform state-speed ease; +} +/* 動きを減らす設定では回さずに向きだけ変える。開いたことの合図は残す */ +@media (prefers-reduced-motion: reduce) { + .article-entry details > summary::before { + transition: none; + } } .article-entry details[open] > summary::before { transform: rotate(90deg); @@ -1641,11 +1673,17 @@ p { details::details-content { block-size: 0; overflow: hidden; - transition: block-size 0.18s ease, content-visibility 0.18s allow-discrete; + transition: block-size state-speed ease, content-visibility state-speed allow-discrete; } details[open]::details-content { block-size: auto; } + /* 動きを減らす設定では高さを送らず、開いた高さで出す */ + @media (prefers-reduced-motion: reduce) { + details::details-content { + transition: none; + } + } } .article-entry li p { font-size: 1em; @@ -3287,8 +3325,9 @@ ul.tag-list { /* タブレット以下はサイドバーを本文の下に落とす (#2044)。 Bootstrap の md(768px〜)で横並びになるが、その幅では列が窮屈。 - 境界はヘッダーメニューの切替(max-width: 1024px)に揃え、 - iPad の縦(768px)横(1024px)ともモバイルと同じ縦積みにする。 + 境界は 1024px で、iPad の縦(768px)横(1024px)ともモバイルと同じ縦積みにする。 + ナビが帯から降りる 992px とは別の境界。あちらは帯に何本並ぶかで決まり、 + こちらは2列にしたときの列の内寸で決まる **鍵は col-md-9。** 75% を作っているのが Bootstrap の列なので、打ち消しも 同じ列で受ける。中身の性格を表す blog-posts で受けていたときは、それを @@ -3727,7 +3766,7 @@ ul.tag-list { 一覧とページャの後ろに出しても読者は辿り着かない(目次を .toc-mobile に移しているのと同じ理由 #2452)。タグとカテゴリの 行き先はヘッダーの検索窓のパネルとナビが持つ (#2885) */ -@media screen and (max-width: 768px){ +@media (max-width: 767px) { .category, .sidebar-series, .sidebar-tags { @@ -3793,7 +3832,7 @@ ul.tag-list { } /* 列数は幅で決め打ちする。column-width で自動に落とすと、幅 576px の端末でも 2列(1列 242px)になって説明文とタグが入らない */ -@media screen and (min-width: 768px) { +@media (min-width: 768px) { .category-index { columns: 2; } @@ -5151,7 +5190,7 @@ a.award-badge:focus { } } .year-tabs input:checked + .tab_item + .tab_content { - animation: tab-fade-in tab-speed ease; + animation: tab-fade-in state-speed ease; } /* 動きを減らす設定では切り替えを瞬時に戻す。0.05秒の色や面の送りは 動きではないので止めない(#2686 と同じ線引き) */ @@ -5211,14 +5250,14 @@ a.award-badge:focus { opacity: 0; } /* **transition は表示される側に書く。** 基底(上)に置くと消える側も - 0.18秒かけて薄くなり、同じマスに重ねてある2枚が同時に見えて文字が重なる。 + state-speed かけて薄くなり、同じマスに重ねてある2枚が同時に見えて文字が重なる。 「出るときだけ送る」形にしたいので、#2686 の「transition は基底側」の 原則をここでは意図して外す */ #monthly:checked ~ .tab-stack > #popular_monthly, #yearly:checked ~ .tab-stack > #popular_yearly { visibility: visible; opacity: 1; - transition: opacity tab-speed ease; + transition: opacity state-speed ease; } /* 動きを減らす設定では瞬時に切り替える。詳細度が同じなので、打ち消しは 必ず上のルールより後ろに置く(メディアクエリは詳細度を上げない) */ @@ -5437,7 +5476,13 @@ a.award-badge:focus { width: 0; padding: 0; opacity: 0; - transition: width 0.15s ease, opacity 0.15s ease; + transition: width state-speed ease, opacity state-speed ease; + } + /* 動きを減らす設定では伸ばさずに開いた幅で出す */ + @media (prefers-reduced-motion: reduce) { + .header-search input { + transition: none; + } } .header-search > button { display: none; @@ -5526,12 +5571,21 @@ a.award-badge:focus { /* 閉じるときだけ visibility を遅らせる。Safari はクリックでリンクに フォーカスを与えず、blur で先に閉じるとタップが着地しない(送信ボタンを モバイルで出していないのと同じ理由)。消えるまでの間に click が届く */ - transition: opacity 0.12s ease, visibility 0s 0.3s; + transition: opacity state-speed ease, visibility 0s 0.3s; } .header-search:focus-within .header-search-hint { visibility: visible; opacity: 1; - transition: opacity 0.12s ease; + transition: opacity state-speed ease; +} +/* ドロップダウンと同じ扱い。閉じるときの visibility の遅延だけ残す */ +@media (prefers-reduced-motion: reduce) { + .header-search-hint { + transition: opacity 0s, visibility 0s 0.3s; + } + .header-search:focus-within .header-search-hint { + transition: none; + } } /* 枠の中のラベル。見出しではなく面の中の仕切りなので h2 は使わない */ .header-search-hint-label { @@ -6111,7 +6165,7 @@ pre.mermaid, color: inherit; min-height: 110px; } -/* 反応はカードの持ち上がりだけにする (#2699)。color: inherit は静止状態にしか +/* 反応は上の「中身が一段引く」だけにする。color: inherit は静止状態にしか 効かず、打ち消しが無いと hover で文字が青くなって下線も出る。 .article-entry を付けるのは、本文の a:hover(0,2,1)に勝たせるため */ .article-entry .link-preview-card-anchor:hover,