パターン

状態メッセージ、記事の表示、ページ内の情報順序を確認できます。読者の目的に合わせて部品を組み合わせます。画面幅を変えて、記事を探す、読む、移動する操作ができることを確認します。

3. 状態の体系

操作中、取得中、現在地、選択を区別します。同じ状態には、部品が変わっても一貫した表現を使います。表示、文言、ARIAで状態を伝えます。

3-1. 操作状態

色の反転だけに頼らず、背景・文字色・ring・opacityの組み合わせで表します。

Defaultsurface + border
Hoveraccent background
Focus visiblevisible ring
Disabledopacity 50%
Invaliddestructive border / ring

3-2. 非同期データの4状態

  • 状態の区別
    • ローディング・表示済み・空・エラーを区別する
  • 回復
    • 回復可能なエラーには再読み込みを用意する
読み込んでいます…
コンテンツを表示
ページがありません
読み込めませんでした再読み込み

3-3. 現在地と選択

  • 現在のページ
    • Headerでは文字の下の青い点で示す。カタログのサイドバーではlink色とsemiboldで示す
    • 見出しのアクセントラインは、現在地の表示へ転用しない
  • 目次
    • 現在の見出しはforeground+medium
  • Command Palette
    • 選択行はaccent面で示す
Page navigation current TOC current
Command Palette selected

7. 記事コンテンツ

記事本文は、見出し、文章、コード、画像、補足、外部参照で構成します。要素の役割に合わせてHTML構造を選びます。読み順と情報の意味を保ちます。

7-1. Markdown本文

  • 幅
    • 本文はReading lane、コードと表はWide laneへ配置する。親の領域幅を超えない
  • 整形
    • 見出し、本文、リスト、インラインコード、コードブロック、引用、表は、記事用の共通スタイルで整形する

セクション見出し

本文は読み続けられる行間を保ち、リンクとinline codeを文章の流れに含める。

小見出し

  • 箇条書きはdiscで示す
  • 番号付きリストはdecimalで示す
const phi = 1.618;
const spacing = phi ** 2;
引用は左4pxの境界とmuted foregroundで本文から分ける。
要素表現
見出し下境界+余白
コードMono+テーマ背景

Source src/pages/posts/[...slug].astro src/styles/globals.css

7-2. Callout

remark-calloutで変換します。

  • 強さ
    • 本文より小さい文字と左境界で、補足の強さを抑える
  • 色
    • 種別の識別だけに使う

Source src/styles/globals.css @r4ai/remark-callout

7-4. Code Copy / Image

  • Code block
    • 言語、横スクロール、Copy操作、完了通知を同じ構造で提供する
  • 画像
    • Figureへ変換する
    • Captionと拡大表示を組み合わせる
const phi = 1.618;
const spacing = phi ** 2;
ブログの栗マスコット

Captionは画像の内容を繰り返さず、読者が確認すべき点を示す。

Source src/lib/articleCode.ts src/integrations/rehypeArticleFigures.ts src/components/article/ImageLightbox.astro src/styles/article-content.css

8. ページの型

ページは、読者の目的、主な構造、固有の部品で分類します。同じ種類のページでは、情報の順序と主要な操作を揃えます。

8-1. ホーム

ブログを紹介し、最新の記事とCosenseのメモへ案内します。

  • 配置
    • プロフィール → Posts → Notesの順に置く
  • 常設しないもの
    • 検索とTag一覧

8-2. 記事一覧

記事を時系列またはタグで探せるようにします。PageHero、タグ一覧、年の見出しとPostListItemの順に配置します。Wideでは、年の見出しを画面内に追従させます。

8-3. 記事ページ

記事の本文、画像、コード、目次の配置と操作を確認できます。

  • 情報構造
    • 文字・画像・コードを、同じ情報構造の中で扱う
  • 幅と表示方法
    • 内容に応じて、読むための幅と表示方法を使い分ける
適用範囲 記事ページのArticle header、本文、目次、画像、コード、参照情報に適用します。

Content model

  • Article
    • 記事を情報構造の中心とする
    • 記事の見出しから目次を生成する
  • 画像とコード
    • 装飾ではなく、本文と同じく意味を伝えるコンテンツとして扱う
KEY OBJECT Article title · description · date · tags
1Article header記事の識別
1..nSection読む順序
0..nFigure視覚的な説明
0..nCode example再利用できる手順
0..1TOCSectionから生成
0..nReference根拠への接続
主要な読書行動
  1. 概要をつかむ
  2. 本文を続けて読む
  3. 図を詳しく見る
  4. コードを確認・コピーする
  5. 見出し間を移動する

Layout

  • 記事ヘッダー
    • 本文と目次より上に置く
    • Wideではタイトルとメタ情報をシェルの1〜12列へ置く。マスコットは置かない
  • 本文・画像・図
    • Reading laneへそろえる
  • コード・表
    • Wide lane(記事内部の9 / 9)へ置く
  • 目次
    • Wideでは13〜16列へ置き、現在位置を示す。CompactとMediumでは記事ヘッダー直後の折りたたみ領域へ置く
ARTICLE HEADER · シェルの1〜12列 記事ヘッダー

タイトルとメタ情報を本文・目次の上に置く。

13〜16列 記事ヘッダー右側の余白

本文横の目次と位置を揃える。

READING LANE · 8 / 9 本文・見出し・リスト・画像・図

視線が次の行頭を見失わない幅を優先する。

WIDE LANE · 9 / 9 コード・表

コードと表には、記事内部の全幅を使う。

WideReading lane + Wide lane + 目次
Medium目次は記事ヘッダー直後の折りたたみ領域
Compact1カラム。目次は記事ヘッダー直後の折りたたみ領域

Typography

  • 文字サイズと行高
    • Compactは16px・行高1.90
    • Medium以上は17px・行高2.00
  • 行長
    • 本文幅の上限は43ic
  • 目的
    • 長文を続けて読める行間を保つ
    • コードや図と行き来しても、本文の位置を見失いにくい行長に制限する
BODY16–17px / 1.90–2.00 / 43ic

Pagefindは静的サイト向けの全文検索ライブラリです。ビルド後のHTMLを解析して検索インデックスを生成するため、専用サーバーを必要としません。

本文の連続性を優先し、視線が次の行頭を見失わない幅に制限する。

Figure

図と文章の左端をそろえて、読書の流れを保ちます。本文幅より小さい画像は引き伸ばさず、枠を画像の幅に合わせます。

  • 配置
    • Reading lane(8 / 9)の左端へ揃え、枠は画像より広げない
  • 画像リンク
    • JavaScriptを利用できない場合は、原寸画像へ移動する
    • JavaScript利用時はDialogで拡大し、小さな文字や細部を確認できるようにする
    • 拡大を閉じた後は、元の画像リンクへフォーカスを戻す
  • Caption
    • 読者が確認すべき点を示す
検索語Astroに一致する記事が並ぶコマンドパレット

検索結果では、記事タイトルを主、公開日と抜粋を従として配置する。画像内の小さな文字まで読める表示幅を確保する。

Code example

  • 文字サイズと行高
    • 14px・行高1.5とし、等幅フォントの語形を識別できる密度にする
  • 言語
    • Shikiが生成するdata-languageから言語名を表示する
  • Copy操作
    • コード領域の右上へ置き、TouchとKeyboardでも見つけられるようにする
    • コピー結果は表示とAccessible name、aria-live="polite"で伝える
  • 長い行
    • コードとコマンドは原則として折り返さない
    • コード領域の中だけで横スクロールさせる
export function getReadingWidth(viewport: number) {
  const readingMeasure = viewport >= 768 ? "43ic" : "100%";

  return {
    readingMeasure,
    lineHeight: viewport >= 768 ? 2 : 1.9,
    fontSize: viewport >= 768 ? "1.0625rem" : "1rem",
  };
}

Source src/pages/posts/[...slug].astro src/integrations/rehypeArticleFigures.ts src/components/article/ImageLightbox.astro src/lib/articleCode.ts src/styles/article-content.css

8-4. 検索ユーティリティ

検索はCommand Paletteで提供します。読者がHeaderのSearchを押したときに開きます。

  • 置かない場所
    • 検索専用のページや、Homeの常設領域は設けない
  • 旧URL
    • 旧URLの/searchは/?search=openへ転送し、同じCommand Paletteを開く

8-5. ポリシー・状態

Privacy Policyでは、本文の行長を抑えます。404ページでは、表示できない状態とトップへの移動手段を伝えます。