目次

スタイルガイド

このブログの見た目の決まりと、その実物を並べたページです。

記事を書くときの記法は 記法ガイド が担います。

黒・灰色は値ではなく役割で選びます。段階の数は「読み手が区別できるか」で決めていて、区別できない差に2つの役割を割り当てません。目安は明度差で、13/255 ほどしか違わない2色は見分けられないので、同じ色と見なしてどちらかの段階に寄せます。

文字(ink)は3段階

3段階とも白背景でコントラスト比 4.5(WCAG AA)を満たします。ink-faint はその条件で置ける最も薄い値で、これより薄くしたいときは文字ではなく別の表現(余白・記号)に変えます。

見本 変数 白背景との比 使うところ
ink-strong 本文・見出し・リンク
ink-mute 本文に添える補助情報(日付・著者・タグ・件数・注記)と引用の本文
ink-faint 空表示・無効と、補助情報の中でさらに弱くするもの(パンくずの >・折りたたみの三角・統計の内訳と枠の名前・引用の中の中黒と連番)

中黒と連番は、その項目の文字より一段弱い段に置きます。本文の中では ink-mute、文字が ink-mute まで下りる引用の中では ink-faint です。

白はスケールの1段階ではなく背景の色そのもので、役割を選ぶ余地がありません。

罫線(rule)は3段階

罫線は「囲うための線」と「切るための線」で役割が違います。枠は形を作るので見え、区切りは読みの邪魔をしない濃さで足ります。ここの比は文字の読みやすさではなく白背景との差の強さを表す数字です。

見本 変数 白背景との差 使うところ
rule-base 枠。カード・チップ・箱・画像枠と、塊の左に引くバー(引用・内訳)
rule-weak 区切り。見出しの下・リストの行間
rule-strong 地を持たない部品の枠(チップ・表)と、focus / hover でひとつ強めるところ(タブの hover の下線もここ)

見出しの下の罫線が薄いのは意図です。節の区切りは直前の空き(56px)が担っていて、線は「そこに境目がある」と気づかせる程度で足ります。読みやすさの指標ではないので濃くしません。

面(surface)は2段階

面は白背景との差だけで意味を出します。濃くすると上に載る文字のコントラストが動くため、白に近い2段階に留めています。

見本 変数 白背景との差 使うところ
surface-tint 静止した面。表のヘッダ・本文末の帯・検索窓
surface-mute hover / focus の面と、空・無効の面・インラインコードの背景

本文のリンクは下線を持つ。色は背景に合わせて替える

色だけでリンクを名乗りません。 色が見えない読者には、青い文字も紫の文字も隣の黒い文字とほぼ同じ濃さに見えます。白背景で AA を保ったまま本文の文字と 3:1 を作れる色は存在しないので、リンクであることは下線が示し、色はそれに添えます。静止して下線が付くのは本文・箇条書き・表のセルの中のリンクで、見出しのアンカーや記事への入口の中のリンクには付きません(カードと記事の行はカーソルを乗せたときだけタイトルに下線が出ます)。

リンクは背景が濃くなるぶん暗い側へ振った段階を持ちます。link-blue は白背景で AA を満たしますが、インラインコードの背景や note の色の付いた背景に乗ると下回るため、同系色のまま暗くした値に替えます。訪問済みは紫で、こちらは白背景でもコードの背景でも足ります。

note の中だけは、色相もその背景から借ります。 注釈は4種類それぞれが色を持っているので、その中の青いリンクは箱の中で唯一の外来色になります。リンクであることは下線が示しているので、色は「その注釈のものである」ことだけを担えます。tip の背景は無彩色に近いため、色相を保つと青になります。

訪問済みは4色に割らず紫のままです。 紫はサイト全体で訪問済みを意味していて、未訪問とは色相で分かれます。種別ごとに割ると未訪問と同じ色相の明るさ違いになり、読んだかどうかが分からなくなります。

リンクがインラインコードを包むときは、明るいほうだけリンクの色が乗ります。 明るい背景ではコードの背景が地より濃い側にあり、そこに濃いリンクの色を乗せても読めます。暗い背景ではコードの背景が地より明るい側にあるので、そこに明るいリンクの色を乗せると読みにくくなります。そこで暗いほうは文字を本体の色のままにして、リンクであることは下線が示します。順序は「これはコードである」が先で、「それがリンクになっている」が後です。

比を取る背景が3種類あるので、下の表はそれぞれの背景に対する比です。note の行は、その注釈の背景と、その中のインラインコードの背景の厳しい方との比を載せています(AA を満たすかはそこで決まります)。

見本 変数 背景 背景との比 使うところ
link-blue 読み物の中のリンク(--a-color
link-visited 訪問済み。インラインコードの中でも同じ値
link-on-tint インラインコードの背景 インラインコードの中のリンク
link-on-note-tip tip の背景と、その中のコードの背景 tip の中のリンク
link-on-note-info info の背景と、その中のコードの背景 info の中のリンク
link-on-note-warn warn の背景と、その中のコードの背景 warn の中のリンク
link-on-note-alert alert の背景と、その中のコードの背景 alert の中のリンク
link-on-note-visited note の4色 note の中の訪問済み。4種類に共通

青は読み物の中のリンクの色です。 レイアウトの導線(「連載一覧へ」のような全件への行き先、パンくず、日付、著者名)には青を使わず、文字のスケールの ink-mute に置いて、反応で ink-strong に1段階濃くします。同じページで本文のリンクと導線が同じ青だと、どちらが読み物の続きなのかが見分けられません。

全件への行き先には末尾に > を置きます。 色を青から ink-mute に落としたぶん、静止した状態ではリンクだと分かる手がかりが色から消えます。文言(「◯◯一覧へ」)と記号の2つで行き先を名乗り、反応では下線が付きます。記号を使うのはこの導線だけで、装飾として他の場所には置きません。

大きさは置かれ方で決まります。単独の行として置くとき(サイドバー・記事末の連載ナビ)は「行として並ぶもの」のスケール、カードの中に入るとき(トップページの特集・著者紹介)はそのカードの説明文と同じ大きさです。カードの中でいちばん弱い情報が、その上の説明より大きくなると、まとまりが崩れて見えます。箱によって説明文の大きさが違うので、導線の大きさも箱ごとに変わります。

選択されると色が消えるので、下線だけが残る

テキストを選択すると、ブラウザは選択範囲の文字も下線も選択の文字色1色で塗り直します。リンクの色は残りません。下線に色を指定しても残りません。選択中にリンクを名乗れるのは下線だけで、ひとつ上の「色だけで名乗らない」がそのまま効いてきます。この段落のリンクを選択すると、実際にそうなります。

このとき、下線は選択の帯に収まっていないと見えません。帯からはみ出した線は背景と同じ色で描かれて消えます。帯の高さは行間で決まるので、いちばん低いのは行間の狭いところ——表のセルです。

そのため本文のリンクの下線の位置は、見た目の好みではなくこの制約で決めています(いま )。記事への入口にカーソルを乗せたときに出る下線も同じ位置です。

ブラウザの描画に決められる値は、スケールに乗せずに理由を添えて置きます。 間隔の4の倍数にも文字の大きさのスケールにも属さない値なので、理由が無いと根拠のない値に見えます。この種の値を増やすときは、まず本当に描画の制約なのか——好みで選べる値ではないのか——を確かめます。

ブランド色

ネイビーは塗り面(フッター)とインタラクション(hover / focus)専用で、文字色には使いません。本文の ink-strong との比が 1.63 しかなく、文字にすると黒と区別が付かないためです。例外は2つの形だけです。1つはネイビーの図形とひと組で読ませる小さな文字で、タブに出る「← → で切り替え」は同時に出るフォーカスリングと同じ色にして1つの信号として読ませ、シェア数はボタンの丸と、著者名は頭文字の丸と1組に見せます。もう1つは、文字がそのページの面そのものになっている 404 の数字です。読み下す文章に混ざる文字には使いません。クリムゾンはコンセプトブックの文法どおり、画面内で同時に1箇所だけの差し色に限定しています。

見本 変数 白背景との比 使うところ
brand-navy 塗り面とインタラクション。フッターの背景・チップ・ページャの現在地・フォーカスリング・テキスト選択の帯
brand-gray 白背景の上で面としてはっきり見せたいところ。小さな部品には広げない
brand-crimson 差し色。フッターの波・ランキング1位・フッターの hover

ネイビーの比 16.34 は「白文字を載せられる濃さ」を、クリムゾンの 5.35 は「白文字で AA を満たす」ことを表します。どちらも文字色としての比ではありません

暗い背景の上は別のスケール

ink / rule / surface は白背景の上で決めた値なので、ネイビー背景では1つも使えません(ink-strong は 1.63 しか出ません)。白背景に3段階置いたのと同じ考え方で、暗い背景の上にもスケールを置いています。比はネイビー背景に対する値です。

見本 変数 ネイビー背景との比 使うところ
on-dark-strong 見出し・強調と、暗い背景でのフォーカスリング
on-dark リンク・本文
on-dark-mute 補助情報
navy-raised 暗い背景の上の面
rule-on-dark 暗い背景の上の線
crimson-on-dark 暗い背景の上の差し色(線・記号)

面と線を同じ値にしません。 明度だけ上げると彩度が残るので(背景も navy-raised も彩度 81%)、1px にすると鮮やかな青の筋に見えます。線は白を薄く重ねた rule-on-dark を使うと、明るくなると同時に彩度が落ちて(50%)色味が引きます。rule-on-dark だけ比が空欄なのは、半透明で明度が確定しないためです。

差し色は役割で分けます。 brand-crimson は暗い背景で 3.06 しかなく線や記号として見えないので、そこには1段階明るい crimson-on-dark を使います。逆に塗り面は brand-crimson のままです(白文字で 5.35。明るい方は 4.51 で余裕がありません)。暗い背景で「読める差し色」と「白文字を載せられる差し色」は同時に成立しません。

ダークモードのスケール

表示テーマは3つあります。端末の設定に従うのが既定で、ヘッダーのボタンで明るい暗いを選べます。2つの切り替えにすると「端末は暗いがこのサイトは明るく読みたい」を表せず、そこから端末の設定へ戻る道も無くなるため、3つ持っています。

暗いほうのスケールは、明るいほうと同じ役割の並びを別の値で作ったものです。背景は色味を持たせず無彩色に寄せています。上の「暗い背景の上のスケール」はフッターのネイビー背景の上でだけ使うもので、彩度があるぶんページ全体の背景には重すぎます。

比はページの背景(dark-surface-base)に対する値です。

見本 変数 背景との比 使うところ
ink-strong 本文・見出し・リンク
ink-mute 補助情報(日付・著者・タグ・件数・注記)
ink-faint 空表示・無効と、補助情報の中でさらに弱くする記号
rule-base 枠。カード・チップ・箱・画像枠
rule-weak 区切り。見出しの下・リストの行間
rule-strong 地を持たない部品の枠と、focus / hover でひとつ強めるところ
surface-base ページと部品の背景
surface-tint 静止した面
surface-mute 反応した面と、空・無効の面
brand-navy フッターの帯

ink-faint は明るいほうと同じく「AA を満たす最も薄い段階」です。 上の表の比はページの背景に対する値ですが、実際にいちばん厳しいのは面のスケールでいちばん明るい surface-mute で、そこでも AA を満たす値にしています。これより薄くしません。

ブランドのネイビーは、暗い背景では背景とほとんど見分けが付きません。 面に使っても線に使っても消えるので、フッターの帯は1段階暗い値にして色味だけ残し、選択中のページ・選択中のタブの下線・共有ボタン・タグの hover・フォーカスリングは明るい線と明るい塗りに置き換えています。

テキスト選択の帯は向きを逆にします。 明るいほうは濃いネイビーの帯に白い文字ですが、暗い背景ではネイビーを中間まで明るくしても、帯として見える前に白い文字が AA を割ります。そこでネイビーを薄くした帯にして、文字を背景の色で描きます。色相はブランドのまま、彩度は半分に落としています(そのままだと蛍光の紫青になります)。無彩色の帯にすると反転表示のように見えて、ブランドの色味が消えます。

同じコントラスト比でも、明るい面は暗い面より膨らんで見えます。 白背景の濃い丸をそのまま反転すると暗い背景では浮きます。同じ強さを移すのではなく、その部品が担う役割から決めます。所在や反応の印は明るいまま、装飾は1段階落とします。

図は紙ごと置きます。 記事の中の図は白い紙の上で描かれていて、線も文字もその紙を前提にした色を持っています。暗い背景へ直接置くと黒い線と文字が沈むので、図の下に白い紙を敷いて、図そのものの色は変えません。線だけをテーマの色で塗り直す手は取りません——箱の背景が透ける図(手書き風の作図など)では、箱の中の文字が暗い背景の上に取り残されます。背景が透過した画像も同じ扱いです。

リンク

背景は2種類です。暗いほうにはインラインコードの背景に乗るリンクの色がありません——コードの背景は地より明るい側にあり、そこへ明るいリンクの色を乗せると読みにくいので、文字は本体の色のままにして下線でリンクを示します。

note の中は暗いほうも色相を背景から借ります。 4色は明るさと鮮やかさをそろえ、色相だけを変えます。色相ごとに鮮やかさの上限を取ると、緑と黄は蛍光色に、青と赤は淡いパステルになって、ひとつの組に見えません。いちばん低い青に合わせて、明るさも鮮やかさも共通の組にしています。

見本 変数 背景
link-blue ページの背景
link-visited ページの背景(訪問済み)
link-on-note-tip tip の背景
link-on-note-info info の背景
link-on-note-warn warn の背景
link-on-note-alert alert の背景
link-on-note-visited note の4色(訪問済み。4種類に共通)

背景に色が付いた面

背景だけ明るいまま残すと、中の文字がテーマ側に付いていって沈みます。 note の4色と表彰の淡い金は、背景ごと暗くしています。ページの背景との差は、面のスケールより1段階上に取っています。上の表の surface-mute と見比べると、帯として1つの塊に見える程度に離れているのが分かります。

見本 変数 背景との差 使うところ
note-tip-bg note tip
note-info-bg note info
note-warn-bg note warn
note-alert-bg note alert
award-card-from 殿堂カードのグラデーション(明るいほうの端)
award-card-to 同(暗いほうの端)
award-card-rule 同・枠
award-gold-on-tint 淡い金の上の金
award-bronze 2回目のメダル

「背景より1段階濃い」は、暗い背景では「1段階明るい」になります。 note の中のインラインコードと表の見出しは、明るいほうでは背景から計算して1段階濃くしていますが、暗いほうは持ち上げる向きが逆になるので値を直接持っています。

インラインコードの背景は、暗いほうでは面のスケールから外れて独自の値を持ちます。 明るいほうは surface-mute をそのまま使いますが、暗いほうで同じことをすると背景との差が note の中の同じ札の半分しか出ず、文中で札として読めません。離す量は note の中の札に合わせています——同じ部品が、置かれた場所で強さが変わらないようにするためです。面のスケールのほうは動かせません(ink-faint の AA がそこで決まります)。

トークンにない色

上のスケールの外に残っている色は3種類で、どれも役割があって残しているものです。

  • note の4色 — 色相を持つ背景。中のインラインコードの背景は、その背景より1段階濃い同じ色になります
  • 表彰・殿堂の淡金 — メダルは灰→銅→金、殿堂のカードは淡金。ブランド色は表彰に広げません
  • コードブロックの構文の色 — 役ごとに1色(キーワード・型名・文字列・数値・キー・タグ・コメントと本文)。詳しくは次の節

どれもテーマで入れ替わります(上のダークモードのスケールを参照)。

ink / rule / surfaceスケールの外にある色はありません段階と数しか違わない色を別の役割として置くと、どちらを使うかの判断ができなくなります。 新しい色を入れるときは、まず近い段階との差を見て寄せられないかを確かめます。

コードブロックの色は役で持つ

コードブロックの色は役で持ちます。色の名前では持ちません。 役と色相の対応はテーマで変わり——キーワードは明るいほうでは赤、暗いほうではオレンジです——「赤」という名前だとどちらかで嘘になるためです。どのトークンがどの役かは両方のテーマで同じで、そこはテーマでは切り替えません。

既製のテーマをそのまま置くことはしません。エディタ用の配色は Web のアクセシビリティ基準を前提にしておらず、明るいほうも暗いほうもそのままではコメント・キーワードが AA を下回ります。色相だけ借りて、明度を基準に合わせます。

比はいちばん厳しい背景に対する値です。明るいほうは背景が5種類あり(本文と note の4種)、そのうち最も暗いものを載せています。

見本 いちばん厳しい背景との比 当たるところ
code-fg 本文。色の付かない部分
code-comment コメント・区切り記号・プロンプト・引用
code-keyword キーワード・組み込み・引数
code-type 型名・関数名・アノテーション
code-string 文字列・文字リテラル
code-number 数値・リテラル・関数・リンク
code-attr 名前と値の組の「名前」。YAML・JSON のキー
code-tag タグ・属性・変数・CSS のセレクタ

暗いほうは背景が1つなので、それに対する比です。

見本 背景との比
code-fg
code-comment
code-keyword
code-type
code-string
code-number
code-attr
code-tag

横スクロールのつまみは罫線のスケールから選ぶ

横に溢れるもの——コードブロックと、横に溢れる表——のつまみは文字ではなく線です。 文字のスケールは白背景で AA を満たすために決めた段階なので、そこからは選びません。罫線の「区切り」の段階を使います。

つまみは中身より前に出るものではありません。 切れ目のない帯は同じ比の文字より強く見えるので、本文と競わない濃さまで引きます。溢れていること自体は折り返しの切り替えが示すので、つまみが唯一の合図ではありません。

テーマごとに1つの値です。 つまみの役割は1つなので、コードブロックと表で分けません。下の比は、その2つの背景のうち厳しいほうに対する値です。

見本 いちばん厳しい背景との比
scrollbar-thumb
scrollbar-thumb(暗いほう)

静止しているときと操作しているときの色は分けられません。 指定できるのはつまみと軌道の2色だけで、掴んでいる間の見え方はブラウザが決めます。

note の中のコードブロックは背景を白で薄める

note の中は同じ色相の3段階になります。コードブロック(いちばん明るい)→ note の背景 → インラインコード(いちばん濃い) の順です。インラインコードは本文に馴染ませるために1段階濃く、コードブロックは別の面として離すために1段階明るくします。「1段階濃い」側はインラインコードが既に持っているので、ブロックは反対側へ離すしかありません。

値は note の背景と白の中間です。「1段階明るい」の幅を決め打ちしないための取り方で、純白にすると差はいちばん開きますが、色の付いた背景の中に無彩色の面が入ります。

暗いほうは3段階の向きが逆で、インラインコードが note の背景より明るく、コードブロックは暗い側にあります。既に別の面として分かれているので、こちらは種類ごとに分けません。

コードブロックは枠線を持たない

輪郭は背景の差だけが作ります。 明るいほうの差は、surface-tint を枠のない面として使っているところ(表の見出し・本文末の帯)と同じで、暗いほうは背景の暗さがそのまま輪郭になります。

ファイル名のタブは内容の幅しか持たないので、枠を入れるとタブと本体の間に横線が残って2つの部品に見えます。枠で囲うなら、タブは本体と同じ幅の帯にする必要があります——それはこのサイトが選ばなかったほうの形です。

文字

大きさ

記事タイトルと本文 h2 が同着になっていないかは、下の並びで確かめられます。

記事タイトル・ページ見出し(.article-title / .list-page / .article-entry h1
見出しはこの大きさで出ます
本文見出し h2(節の始まり。直前の空き 56px と罫線を持つ)
見出しはこの大きさで出ます
本文見出し h3(直前の空き 32px)
見出しはこの大きさで出ます
本文見出し h4(直前の空き 24px)
見出しはこの大きさで出ます
本文見出し h5(本文と同じ大きさ。太字であることが見出しの印)
見出しはこの大きさで出ます
本文見出し h6(最下層)
見出しはこの大きさで出ます

部品の大きさは7つの段から選びます。 値ではなく役で選べるように、段に名前が付いています。

添え・注記・件数・小ラベル
メタ行・パネルの説明・タグの件数。読者の行動を変えない数字と、部品の名前
土台
ページ全体の既定値。コードブロックの1行もこの大きさです
行として並ぶもの
ナビ・目次・パンくず・全件への導線。読み下す対象ではなく、目で拾う対象です
読み下す文章
記事本文・特設ページの本文・記事の概要文・カードの題。段落を何行も追う場所です
サイト名・サイドバーの見出し
枠の名前
見出し・ロゴ
一覧カードの記事名
大見出し
節の始まり

段の外にあるのは3つだけです。記事タイトルは幅で変わるので clamp で持ちます。404 ページの数字は1箇所でしか使わない一点ものです。行き先の名前に添える総数は、いちばん下の段でも名前と 1px しか違わず名前の一部に見えるので、段より小さく置きます。タグのチップの件数もこの総数と同じ役なので、同じ値です。

見分けの付かない差に2つの役を割り当てません。 新しい部品の大きさを決めるときは、まず近い段との差を見て寄せられないかを確かめます。1px 未満しか違わない2つの値は、読者には同じ大きさに見えます。

note の中は、外の組をそのまま1段下げます。 中の文章は本文より1段小さく、中のコードブロックと表のセルもそこから1段小さくなります。note に書くのは本文の脇に置く補足なので、本文と地続きの大きさでは読ませません。背景の色が箱の範囲を示し、大きさが本文との主従を示します。 段は部品ごとに役で選びますが、note の中だけは「外の組から1段」で決まります。

上の本文見出し h2〜h6 は段の外です。あちらは互いの比が階層を作る列なので、土台の大きさに追従する必要があります。

見出しの階層はサイズだけでなく、サイズ・太さ・直前の空き・罫線の4つで作ります。サイズだけで表そうとすると上下が詰まります。避けたいのは同着で、比を大きく取ること自体が目的ではありません。記事タイトルの下限を上げるとモバイルで字数が足りなくなるため、太さ(800 対 700)とページ先頭という位置、h2 側の空きと罫線が階層を支えています。

行間

段階は3つだけです。1つの役割に1つの値しか持ちません。下の見本は同じ大きさの文字を3つの段階で組んだもので、差は行送りだけです。

見出し
見出しは1〜2行で終わるので、行を追うための空きは要りません。長い記事タイトルが2行になったときに、上下の行が1つの塊として読める程度に留めます。
読み下す文章
和文は仮想ボディいっぱいに字が入るので、欧文と同じ行送りでは行が貼り付いて見えます。段落を何行も読み下す場所は、目が次の行の頭へ戻れるところまで開けます。
行として並ぶもの
一覧の1件・目次・チップ・タブは読み下す対象ではなく、目で拾う対象です。開けるほど帯が縦に伸びて、一度に見える件数が減ります。

役割の割り当ては次のとおりです。

段階 使うところ
見出し 記事タイトル・ページ見出し・本文の h1〜h6・サイト名・カードとパネルの見出し
読み下す文章 記事本文・特設ページの本文・note の中・フッターの説明
行として並ぶもの 記事一覧・年別一覧・目次・パンくず・ページャ・タグのチップ・タブ・カードの説明・コードブロックの1行

アイコンや順位の丸のように1行しか入らない小さな箱では、line-height は行間ではなく箱の高さを決める値です。字を丸の中心に置くために 1 を使う場所があり、これは行間のスケールの外にあります。

太さ

段階は3つだけです。中間の段階(500 / 600)は置きません。フォント側に該当ウェイトがないとブラウザの合成太字になり、輪郭が濁ります。

太さ 使うところ
400 本文と、行として並ぶ記事名(ランキング・関連記事・参照記事・連載ナビ・記事一覧)
700 見出し全般と、カード・パネルの見出し
800 ページの主題(記事タイトル・ページ見出し)

13〜14.3px の記事名を太らせると、隣のメタより先に帯全体が重くなります。行の中の主従は「メタから太字を外す」側で作ります。

間隔

間隔は4の倍数だけを使います。 上限は決めず、刻みだけを置いています。

段階を数え上げないのは、使う値が並びの間隔だけでも 4〜48px と幅広く、どこで打ち切る理由も無いからです。刻みを4pxに揃えておけば隣の段階が必ず 4px 差になり、5px と 6px のように見分けの付かない差が生まれません。色を3段階に絞ったのと狙いは同じで、迷う余地を減らすためです。

入れ子の箇条書きは、開きではなく戻りに空きを置きます。 親の項目から子のリストへ入るところは字下げが1段深くなること自体が切れ目を示すので詰めておき、子のリストが終わって同じ階層の項目に戻るところに刻み1つぶんを置きます。両方に空きがあると、どちらが階層の切れ目なのかが読めなくなります。

ページの最大幅は種類で変えません。 記事も一覧もトップも同じ枠に入ります。読む対象が変わってもページの左端と右端が動かないので、どのページでも同じ場所を見に行けます。

左右の空きは全幅で 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 検索窓が虫眼鏡だけになり、フォーカスされたときだけ帯を覆って広がる。一覧カードのサムネイルが文字の上に積む すべての記事
768px サイドバーの探索の枠が消える。2列で並べていた一覧が1列になる。コードと note が画面の端まで伸びる カテゴリ一覧
992px ヘッダーのナビが帯から降りて引き出しに入る。フッターが4列から2列になる トップページ
1025px 本文とサイドバーが縦に積む。サイドバーの統計とグラフは消え、目次は本文の上の折りたたみに移る。ヘッダーの帯は追従をやめて本文と一緒に送られる 記事ページ

中間の幅を作りません。 段階を増やすと、どの幅で確かめた見た目なのかを追えなくなります。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段階

小さな部品・箱・ピル(チップの形。円も同じ値)の3つだけで、中間の段階(3 / 5 / 6 / 10px)は置きません。段階が増えると「どれを使うか」の判断ができなくなります。

小さな部品 4px 箱 8px ピル 999px

小さな部品はチップ・サムネイル・操作部品、箱はカード・コードブロック・note・details です。

チップは枠だけで作り、地を持ちません。 地を敷いても白背景との差が 1.09 しか出ず、形を作っているのは枠の方だからです。そのぶん枠は rule-base ではなく rule-strong を使います(白背景との差が 1.36 から 1.61 になります)。

影は持たない

影は1段階も持ちません。読み物を並べる場所では輪郭をなるべく作りません。 記事へ送るカードは囲みを持たず、1件のまとまりは外の空きが中の空きより十分大きいことが作ります。連載一覧や特設ページのパネルは、隣の列との間が 48px で、サムネイルと文字の間(12px)の4倍です。トップページの「特集」は、隣の枠との区別をサムネイルを上に載せる向きが付けます。枠線を持つのはリンクプレビューだけです。タブも枠を持たず、切り替わる範囲は帯の下辺の線が示します。操作部品(検索窓・ドロップダウン)と、中身をまとめて囲む枠(統計・折りたたみ・年月のカード)はこの範囲の外です。枠がその部品の範囲そのものを作っているので、外すと境目が読めなくなります。

hover は1部品1反応

同じ「押せる」の合図なので、速さも1つだけです。秒数の決まりは下の「時間」がまとめて持ちます。

反応は入れ子のうち外側だけが返します。

部品 反応 実物
記事への入口(カード・行) タイトルに下線が付き、画像が1段階引く トップページの連載・特設パネルと「よく読まれている記事」
ナビゲーションの行 面が付く サイドバーのカテゴリ・タグ、ヘッダーのドロップダウン
本文のリンク 下線が1段階太くなる このページの本文のリンク
そのほかの裸のリンク 下線が付く パンくず・日付・著者名
チップ 背景が1段階変わる タグ一覧
アイコンだけのリンク 背景が1段階変わる(チップと同じ) 記事ページのシェアボタン

アイコンだけのリンクにチップと同じ反応を持たせるのは、下線が引く相手を持たないからです。絵柄に下線を引いても何も起きたように見えないので、丸い背景を持たせてそこを1段階変えます。

下線と背景は同時に動きません。 背景が変わる部品(ナビゲーションの行・チップ・アイコンだけのリンク)では下線を出さず、下線が付くのは背景を持たない部品です。本文のリンクのほか、パンくず・日付・著者名・カテゴリ名・タグクラウド・「すべての連載を見る」のような全件への導線、そして記事への入口のタイトルがこれにあたります。どちらか一方しか動かないので、部品ごとにどちらだったかを覚える必要がありません。

記事への入口が下線側なのは、背景も囲みも持たないからです。以前は中身の色を1段階落として返していましたが、その差は 1.62:1 しかなく、反応が起きたことを読み取れませんでした。状態は前後を並べて比べられないので、同時に見える2色の判別より大きい差が要ります。文字色を濃くする方向はもう無い(ink-strong が最も濃い段階)ため、色ではなく下線に替えています。

カードでも行でも反応は同じです。 記事一覧のカードと「よく読まれている記事」の行は、どちらもサムネイル・タイトル・年月の組で、同じ「記事1本への入口」です。形が違うだけで反応が変わると、読者からは同じものが場所によって別の動きをすることになります。当たる範囲は行のほうが広く、行のどこを押しても記事へ飛びますが、反応は行き先を名乗るタイトルと画像に出します。押せる範囲より反応が狭いぶんには、押しても何も起きないという裏切りは起きません。特集や連載のパネルも同じで、説明文や余白を押しても行き先へ飛びます。本文末の帯にある We’re hiring も、カードの形の1行き先としてここに入ります。

記事本文に貼るリンクプレビューも同じ型です。行き先が外部ページでも、カード1枚が1つの行き先を名乗る形は変わりません。囲みを持つ数少ない部品ですが、囲みの有無で反応は変えません。実物はこの記事にあります。

反応が出るのは、記事へ行くリンク——サムネイルとタイトル——を指している間だけです。 記事一覧のカードには日付・著者・カテゴリ・シェアボタンという別の行き先も並んでいて、カードに乗っていること自体を合図にすると、そこを指している間もカードが「この記事へ行く」と名乗ってしまいます。カーソルの真下にあるのは別の行き先なので、両方が同時に名乗ると押した先が読めません。

この線引きは、指している瞬間だけを止める形では引けません。 別の行き先どうしの間には隙間があり、メタ情報の項目の間で 28px、シェアボタンの丸の間で 12px あります。そこで反応が戻ると、メタ情報の上を1回なぞるだけで6回以上ついたり消えたりして点滅に見えます。カードの中の余白は連続した1つの面ではなく、行き先と行き先の隙間なので、余白での反応は誘いとして働くより先にノイズになります。

背景で返すのはナビゲーションの行です。サイドバーの軸やヘッダーのドロップダウンのように、メニューの項目が縦に並ぶ場所では、行の背景が変わるのが通り相場です。読み物の中に置いた記事の入口は、ここから外れます。

ヘッダーの帯の中だけは、下線も背景も動かさず文字色を1段階濃くします(帯から下がるドロップダウンの行は背景が変わります)。

フッターのリンクだけは例外で、下線が左から伸びます。開閉・展開は反応ではなく状態の変化なので、別の時間を持ちます。タブの切り替え、ドロップダウンと引き出しの開閉、検索窓の拡張、折りたたみの開閉がこれです。

フォーカスリング

キーボードで辿っている場所の目印は、ネイビー 2px のフォーカスリング1つです。反応(hover)と所在(focus)は別の役割なので、フォーカスリングに差し色を使いません

リングは所在だけを示すので、反応は反応で別に返します。 記事への入口・目次・年月のカードは、キーボードで行き先を名乗るリンクに来たときにも、カーソルを乗せたときと同じ反応(タイトルの下線・画像の引き・面)を出します。リングだけにするとキーボードで辿る読者だけが「押せばこの記事へ行く」という合図を受け取れません。ヘッダーの帯の中だけは例外で、64px の帯に下線を重ねると合図が2つになるためリングだけにしています。

暗い背景(フッターとヘッダーの帯)ではネイビーが見えないので、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つだけ動かして表します。動かすのは太さか面のどちらか一方で、両方は動かしません。

現在地(active / current)

表し方は2通りあり、その部品がクリックできる面(ヒットエリア)を持つかどうかで決まります。文字だけが並ぶ帯では太字にし、ヒットエリアを持つ部品では面を塗ります。帯の中で面を塗ると現在地だけが浮き、ヒットエリアを持つ部品で太字にすると押せる範囲が変わらないので所在が読めません。

リンク hover 中のリンク下線 現在地太字

パンくずの帯がこの形です。3つが同じ色のまま素・下線・太字で見分けられます。色は動かしません。 14px の帯の中で色と太さを同時に動かすと、現在地だけが黒く浮いて見えます。

部品 表し方 実物
パンくず 太字 すべての記事 の2ページ目
ページャ 現在のページだけネイビーの丸で塗る。省略の「…」は塗らない すべての記事 の2ページ目
タブ 下線がネイビーになり、太字になる。塗りにすると中身より目立つ トップページ

現在地はリンクにしません。押しても同じ場所に来るリンクは、行き先を辿るときに空振りになります。目で見る読者・支援技術・機械の3方向に同じ違いを渡すため、太字と併せて aria-current="page" を付けます。

無効・空(disabled)

このサイトには押せなくなるボタンやフォームがありません。代わりに「まだ無い」「もう押せない」を表す形が3つあります。

かたち 表し方 実物
中身が無い 文字は ink-faint、面は surface-mute。枠と大きさは中身があるときと同じに保ち、場所だけ空けておく すべての記事 の投稿が無い月、連載一覧 のサムネイルが無い連載
押せない リンクにせず、hover にも応えない。手の形のカーソルが出る部品では cursor を既定の矢印に戻す すべての記事 の投稿が無い月、ページャの「…」
押す対象ではない補助情報 押せる部品のに出す。シェア数はボタンの下に置き、押せる範囲と数字が別だと位置で示す 記事ページ のシェア数

歯抜けを詰めません。 投稿が無い月を一覧から落とすと、無いのか見落としなのかが読者に区別できません。同じ大きさの空き枠を置いて、無いことを見えるようにします。

ink-faint は白背景でコントラスト比 4.5 を満たす最も薄い文字色です。これより薄くしません。 「無効だから読めなくてよい」ではなく、無効な項目も何であるかは読める必要があります。

部品

note

背景は4色あり、色相を持ちます。中のインラインコードの背景は、その背景より1段階濃い同じ色になります。4色でも表のヘッダでも同じ規則が効きます。リンクも色相を背景から借りますが、訪問済みだけは4色に共通の紫です。リンクがインラインコードを包むとき、暗いテーマでは文字が本体の色のままになります(下線がリンクを示します)。明るいテーマではリンクの色が乗ります。以下の4色すべてで同じで、下の見本はどれも素のリンクとコードを包んだリンクを並べています。書き方は記法ガイドにあります。

中の文章は本文より1段小さく、コードブロックと表のセルもそこから1段小さくなります。行間は本文と同じです。

tip の背景です。知っておくと得をすることに使います。リンクは部品ギャラリーのように背景の色相を借り、series のようにコードを包むと、暗いテーマでは文字が本体の色に戻ります。

info の背景です。読み進めるうえで知っておいてほしいことに使います。記事一覧authors のような行き先を添えられます。中に置いたコードブロックと表も、外より1段小さくなります。

npm audit fix
セル セル

warn の背景です。気をつけないと困ることに使います。連載一覧categories も、背景の色相を借りる点は変わりません。

alert の背景です。踏むと壊れることに使います。一度開いたタグ一覧specials は、4色に共通の紫に変わります。

ヘッダに背景色(surface-tint)を敷き、本文行は白で揃えます。全セルの罫線が行を追う役割を果たしているので、縞は入れません。横に溢れる表は .scroll が受けます。

セル セル セル
セル セル セル

チップ

タグはピル型のチップで表します。枠だけで地を持たず、hover で背景がネイビーに変わります。右肩の件数は、サイドバーやヘッダーの一覧で名前に添える総数と同じ役なので、同じ大きさ・同じ ink-faint です。hover で地が反転する間だけ、反転後の文字色を継ぎます。実物はタグ一覧にあります。

この形を借りるのは、記事タイトルの上で名乗るチップ(受賞・連載)だけです。アイコンを持ち、太字で文字色が一段濃いので、タグのチップとは見分けが付きます。反応は地がネイビーではなく灰に変わります。実物は受賞記事連載の記事にあります。

群のある一覧

行き先が多い一覧(タグ一覧の「すべてのタグ」は全件を並べます)は、頭文字や年で群に分け、左のラベルが群を名乗る行に並べます。群の範囲は空きではなく行の上下の罫線が示します。群が多いときは節の先頭に群への飛び先を1行置きます。実物はタグ一覧著者一覧にあります。

1件が数行にわたる一覧では、ラベルを行の左ではなく群の上に置きます。このときの群の範囲は罫線ではなく空きが示し、群の切れ目を件と件の空きのちょうど2倍にとります。ラベルは件より少しだけ字下げの外に出しますが、階層を作るのは空きの側なので強くは振りません。2列に並べるときは、行の高さを左右でそろえるグリッドではなく多段組にします。グリッドだと背の低い側の下に余りが出て、同じ群の中の空きが群の切れ目より広くなることがあり、空きが階層と逆のことを言い始めます。実物はカテゴリ一覧にあります。