Days Elapsed

Share

一年を「面」で見る

一年は365日。数字で見ると多いけど、並べてみると案外少ない。

12ヶ月を並べて、過去を塗りつぶして、今日を光らせる。それだけのカレンダーを作った。進捗バーが「一次元」なら、これは「二次元」の進捗表示。

Year Progress
一年は50週ちょっとしかない 2026年を週で数えると、52週とちょっと。 カレンダーで見ると長そうなのに、週で数えると急に短くなる。そんな感覚を形にしたくて、このページの上の方に進捗バーを置いた。 やっていることは単純で、「今年が何%進んだか」をリアルタイムで表示しているだけ。 なぜ作ったか 理由は3つある。 1. 時間を「量」として見たかった ── イベントや予定ではなく、単純に「どれだけ経ったか」を数値で見たかった。 2. 目に見える形にしたかった ── 抽象的な「一年」を、動く数字に落とすとどう感じるか試したかった。 3. 自分の場所に置きたかった ── 誰かのツールを借りるのではなく、自分のブログに自分で作ったものを置きたかった。 実装の話 せっかく作るなら、それなりに丁寧にやりたかった。 * Web Components で実装。ブログのCSSやDOMを汚さず、どこにでも持っていける。 * requestAnimationFrame で描画。固定間隔のタイマーではなく、画面更新に同期させることで滑らかさとリソース

これは一年の進捗バー


なぜ作ったか

進捗バーでは「どれだけ進んだか」はわかる。でも「今どこにいるか」は見えない。

  • 空間で把握したかった ── 線ではなく面で。12月がどこにあるか、今が年のどのあたりか、一目でわかるようにしたかった。
  • 月の重みを感じたかった ── 1月も12月も同じ1マス。でも並べると、過ぎた月と残った月の差が目に見える。
  • GitHubの草が好きだった ── あの「塗りつぶされていく感覚」を、一年単位で味わいたかった。

設計の話

レスポンシブは妥協しない

最初は GitHub 風の「7行 × 53列」で作った。見た目は良かったけど、スマホで横スクロールが発生して使い物にならなかった。

解決策は「月ベースのレイアウト」。12ヶ月を並べて、画面幅に応じて 4列 → 3列 → 2列 と自動で切り替わる。Container Queries を使って、親要素の幅に反応するようにした。

@container (min-width: 600px) {
  .year { grid-template-columns: repeat(4, 1fr); }
}
@container (min-width: 400px) and (max-width: 599px) {
  .year { grid-template-columns: repeat(3, 1fr); }
}

どの画面でも横スクロールは発生しない。

日付変更を正確に検知する

0時0分0秒に「今日」が移動する。そのタイミングを逃さないために、次の0時までの残り時間を計算して setTimeout をセットしている。

タブがバックグラウンドにあると JavaScript のタイマーは信用できないから、visibilitychange で復帰時に再チェックする仕組みも入れた。

色はすべて oklch()

従来の hsl() は、同じ彩度・明度でも色相によって見た目の明るさが変わる。oklch() は知覚的に均一な色空間で、hue を変えるだけで一貫した見た目が保てる。

--_past: oklch(55% 0.15 var(--_hue));
--_today: oklch(65% 0.22 var(--_hue));

緑でも青でも紫でも、--calendar-hue を変えるだけでテーマが変わる。


アクセシビリティ

派手なアニメーションは人を選ぶ。

  • prefers-reduced-motion ── アニメーションを無効化。今日のセルも静的な強調に切り替わる。
  • forced-colors ── Windows のハイコントラストモードでも、過去・今日・未来が区別できるようにした。
  • aria-label ── スクリーンリーダーには「2025: 364/365 (99.7%)」のように進捗を読み上げる。

見た目だけじゃなく、見えない人にも情報が届くようにした。


年末に眺める

今、このカレンダーを見ると、ほとんど塗りつぶされている。残っているのは数日だけ。

来年の1月1日になったら、すべてが空になる。そしてまた少しずつ埋まっていく。

その繰り返し。

Read more

Dependabotの対応が面倒なのでRenovateを導入する

Dependabotくんはある程度の依存関係の更新を通知してくれるが、山のようにprojectを抱えているとなんとも痒いところに手が届かない。 ということで、Renovateを使ってみる。 Build software better, togetherGitHub is where people build software. More than 150 million people use GitHub to discover, fork, and contribute to over 420 million projects.GitHub ここからGitHub Appを入れる。 あとは、指示に従ってポチポチするだけで、超かんたんだった。 感想 自動化最高。

By Sakashita Yasunobu

nodejsのバグを見つけたのでPRを投げてみた

概要 要するに、node --testで特定のバイナリを標準出力に書くと、テストランナーが固まったり、異常終了したりするバグです。 バグ自体は既知のものだったようで、修正がされていました。 test_runner: infinite loop in FileTest#drainRawBuffer when child stdout contains FF 0F followed by large size bytes · Issue #62693 · nodejs/nodeVersion v25.9.0 (also reproduced on v24.14.1 LTS, v22.21.0 LTS, v23.4.0) Platform Darwin 25.

By Sakashita Yasunobu
青空文庫のParser

青空文庫のParser

青空文庫のParserを作ってます。 GitHub - P4suta/aozora: Pure-functional Rust parser for 青空文庫記法 (Aozora Bunko notation): ルビ, 傍点, 縦中横, 外字, 返り点, indent containers, page breaks.Pure-functional Rust parser for 青空文庫記法 (Aozora Bunko notation): ルビ, 傍点, 縦中横, 外字, 返り点, indent containers, page breaks. - P4suta/aozoraGitHubP4suta Rustで作ってますが、配布物はcargoのほかにnpm/pypiでも入手できます Documentation * Playground — try it in

By Sakashita Yasunobu