いま映している時刻を、名前をつけた速さの段で動かし、決まった幅で飛ばし、ひと押しで「いま」へ戻すための操作盤です。監視盤の巻き戻し、ログの再生、運行の再現、シミュレーションの早送りのように、連続した値の上を読み手自身が行き来する画面で使います。
この記事では、速さを連続値にしない理由、ひと押しで「いま」へ戻せるようにする理由、向きをアイコンに持たせてボタンの文字に書かない理由、状態を大きい表示の色で示さない理由を順に説明します。判断の要点は全部で 7 つありますが、とくに効くのは最初のこの 4 つです。
1. UI例(Preview / Live)
実装で見る(GunjoUI)
この部品を、デザインシステム GUNJO の実装で確かめられます。
2. 定義(Definition)
Time Transport は、連続した値の上の現在位置を読み手に動かさせるための操作盤です。持っているのは次の 4 つの操作と 2 つの表示です。
- いま映している位置の表示:大きい数字と、その下の補足(日付、タイムゾーン、いまからの隔たり)
- 状態の札:いま映している位置が「いま」と同じかどうかを、大きい数字の横に短い文字で出す
- 速さ:「1 分 / 秒」「1 時間 / 秒」のように、あらかじめ用意した選択肢(段)から 1 つ選ぶ
- 再生と一時停止:選んだ速さで位置を進める
- 決まった量の飛ばし:1 時間、1 日のように、飛ぶ量を決めて飛ぶ
- いまへ戻る:ひと押しで現在位置を「いま」に戻す
この記事で使う言葉:いま映している位置が「いま」と同じ状態を「実時間」、そこから離れた状態を「いまから外れている」と呼びます。この「実時間」は位置の状態の名前で、速さの選択肢のひとつ(1 秒で 1 秒進む速さ)とは別の話です。
Slider との違い:Slider は値を選ぶだけのコンポーネントです。速さも再生も「いまへ戻る」も持ちません。操作盤は、位置を選ぶだけでなく、位置が動き続ける状態を扱います。
動画プレイヤーとの違い:動画には終わりがあり、全体の長さが決まっています。この操作盤が扱うのは未来側に終わりが無い列(いまも増え続けるログや計測値)で、未来側の端は「いま」です。過去側には記録の先頭があります。だから「いまへ戻る」が要ります。
Calendar や時刻ピッカーとの違い:Calendar は決まった日時を選ぶコンポーネントです。この操作盤は「ここから 1 時間戻す」のように相対で動かします。
時計を持たないこと:時間を進める仕組み(1 秒ごとに位置を足す処理)は、操作盤の中に置きません。操作盤は、いまの位置を受け取って表示し、読み手が押したことを画面側に伝えるだけです。進めるのは、この操作盤を画面に置く側です。中に時計を持つと、最初に表示される時刻が一瞬ずれて見えることがあり、動作確認のときにも時刻を固定できなくなります。
3. 使い分け(When to use / When NOT to use)
3.1 When to use
- いまも増え続ける列を見る:監視盤、運行、センサー、アクセスログ
- 過去のある時点の状態を見に行きたい:障害の直前、混雑の山、事故の前後
- 速さを変えて眺めたい:8 時間ぶんを数分で流し見る
- 何度も「いま」に戻る:見に行って戻る、を繰り返す画面
- 同じ幅で刻んで比べたい:1 時間ずつ送って変化を見る
3.2 When NOT to use
- 1 点を選ぶだけ:時刻を 1 つ入力させたいなら時刻の入力欄を使います
- 終わりのある動画や音声:専用の再生器のほうが読み手の予想に合います
- 過去のデータが無い:巻き戻す先が無い盤に、操作だけ置かないようにします
- 動かす対象が 1 画面に複数ある:どの表示が動くのかが読めません。対象を 1 つに絞ります
- 速さの段が 1 つしか無い:速さの選択は出さず、再生だけにします
3.3 代替UI(Alternatives)
- 値を 1 つ選ぶだけでよい : Slider(スライダー)
- 日を選ばせたい : Calendar(カレンダー)
- 段の選択だけが要る : Toggle Group(トグルグループ)
- 1 日の中の位置を面で見せたい : Day Band(いちにちの帯)
- いまの値かどうかを示したい : Live Badge(LIVEの札)
- 出来事を並べて見せるだけでよい : Dashboard Patterns(ダッシュボードパターン)
4. 設計判断の核(Decision Principles)
この操作盤の核は「速さを連続値にしないこと」。倍率のつまみは作る側には自然だが、読み手は倍率から中身を読み取れず、同じ速さにも戻せない。
判断は 7 つあり、とくに効くのは最初の 4 つです。1. 速さを段にして名前を付ける、2. 「いまへ戻る」を常に置く、3. 向きをアイコンに持たせる、4. 状態を色ではなく文字で言う。5. 渡さなかった操作を出さない、6. 時計を操作盤の外に置く、7. 触れるところの高さを確保する。
- 速さは連続値ではなく、名前のついた段にする:GUNJO(群青)は UIXHERO が作っているデザインシステムです。その
TimeTransportのもとになったのは天体の運行を見せるアプリで、そこでは速さが 1 倍から 1000 万倍までの連続値でした。天体を見るなら自然な刻みですが、読み手が受け取るのは「いま何倍か」という数字だけです。1 秒で 1 時間進むのか、1 日進むのかは、倍率からは暗算になります。さらに、連続値では一度離れた速さに戻せません。段にして「1 時間 / 秒」と名前を付けると、選ぶことと戻ることの両方ができます。名前を付けるのは呼び出し側(この操作盤を画面に置くページの実装)の仕事です。速さ 1 段ぶんが、1 秒で 1 分進むのか 1 日進むのかは、コンポーネントには分かりません。 - 「いまへ戻る」を脱出口として常に置く(「いま」が存在する列では):時間を動かせる画面は、読み手を迷子にします。3 時間前まで戻り、10 分ずつ送り、どこにいるか分からなくなる、という道筋です。ひと押しで現在位置に戻れることが、その画面で試してみる気持ちを支えます。いまを映しているあいだ(位置が「いま」と同じあいだ)は、押せない状態にします。もう戻っているので、押せると見せると空振りになります。
- 向きはアイコンに持たせ、ボタンの文字は量だけにする:飛ばしの量は符号付きで受け取り、負の側を左、正の側を右に振り分けます。ボタンの文字に「前へ」「後へ」と書かず、量(1 時間、1 日)だけを書きます。並びの左右とアイコンが向きを示すので、押す前に読む文字が減ります。そのまま多言語に出せるという効き目もあります。
- 状態を大きい表示の色で示さない:いまから外れたときに、大きい時刻の色を警告色に変えたくなります。ただし意味を示す 3 色(緑・黄・赤)は、盤の薄い背景の上に文字色として置くとコントラストの基準(4.5:1)に届きません。状態は札が文字で言っているので、色に頼る必要がありません。上のデモの下段で、届かない側と読める側を並べています。札そのものの設計は Live Badge に分けて書いています。
- 渡さなかった操作は出さない:速さの段を渡さなければ速さの選択は出ず、再生の関数を渡さなければ再生ボタンは出ず、飛ばしの量を渡さなければ飛ばしのボタンの列は出ません。「いま」の位置も実時間かどうかも渡さなければ、札と「いまへ戻る」は描かれません。推測して間違った状態を見せるより、黙っているほうが正しいという判断です。押しても何も起きないボタンは、読み手にとって壊れているのと同じです。
- 時計を操作盤の外に置く:位置を進めるのは呼び出し側です。2 章で書いたとおり、時間を進める仕組みを操作盤の中に入れると、最初に表示される時刻が一瞬ずれて見えることがあり、動作確認のときにも時刻を固定できなくなります。呼び出し側でも、いまの時刻を描画中に読まないようにします(画面が出たあとに動く処理の中で読みます)。
- 触れるところは高さ 44 ピクセルを割らない:再生、飛ばし、いまへ戻るは、どれも繰り返し押されるボタンです。ボタンの文字が「1 時間」のように短いので、文字の幅に合わせると小さくなりすぎます。高さを固定します。
5. 状態設計(States)
状態は 2 つの軸で決まります。いまを映しているか、そこから外れているかと、位置が自動で進んでいるか、止まっているかです。この 2 軸の外に「操作できない」があります。表示に出る文字は「実時間」と「いまではない」の 2 つで、「実時間」は状態の名前としても使います。
5.1 必須状態(Required)
- 実時間:いま映している位置が「いま」と同じ。札が実時間と言い、「いまへ戻る」は押せない
- いまから外れている:札が「いまではない」に替わり、「いまへ戻る」が押せる
- 止まっている:再生していない。位置は読み手の操作でしか動かない
- 操作できない:盤全体が無効。読み取り専用の盤や、再生するものが決まっていないとき
5.2 条件付き状態(Conditional)
- 再生中:再生ボタンが押された状態になり、一時停止の形に替わる
- 記録の先頭に着いた:これ以上戻れない。その向きの飛ばしを押せない状態にします(未来側の端は「いま」です)
- データが欠けている区間:位置は動くが値が無い。操作盤ではなく、映している側が言います
- 速さの段が 1 つだけ:選択の意味が無いので、段の列を出しません
- いまを追い続けている:「実時間」が「いまと一致している状態」を指すのに対し、こちらはその一致を自動で保ち続ける設定です。再生とは別で、速さに関係なく「いま」に貼り付きます。読み手が動かした瞬間に、追うのをやめます
5.3 State Gallery
| 状態 | 必須 | 何を伝えるか |
|---|---|---|
| 実時間 | 必須 | 映しているのは、いまの値である |
| いまから外れている | 必須 | 映しているのは過去の位置である |
| 止まっている | 必須 | 位置は自分で動かす |
| 操作できない | 必須 | いまは動かせない |
| 再生中 | 条件付き | 選んだ速さで位置が進んでいる |
| 記録の先頭 | 条件付き | この向きにはもう動けない |
| データが欠けている区間 | 条件付き | 位置は動くが、そこに値が無い |
| 速さの段が 1 つだけ | 条件付き | 選ぶ意味が無い(段の列を出さない) |
| いまを追い続けている | 条件付き | 手を離しても、いまに付いていく |
6. バリエーション設計(Variants)
渡した操作の数で決まります。渡さなかったものは出ません。ただし「いまへ戻る」だけは札と同じ組(「いま」の位置)に載っているので、札と一緒に消えます。
| バリアント | GUNJO の指定 | 典型的な用途 |
|---|---|---|
| 全部そろった盤 | 速さ、再生、飛ばし、いまの位置を渡す | 監視盤、運行の再現 |
| 飛ばしなし | jumps を渡さない | 速さと再生だけの、いちばん小さい形 |
| 速さなし | speeds を渡さない | 1 時間ずつ送るだけの盤 |
| 再生なし | onPlayingChange を渡さない | 読み手が自分で刻んで送る盤 |
| 札なし | now と live を渡さない | 「いま」の概念が無い列(完結した記録) |
| 掴んで動かす面つき | scrubber に帯を差し込む | 1 日の帯を入れて、掴んで動かす |
| 操作できない | disabled | 読み取り専用、または対象が未決定 |
掴んで動かす面は、盤の一部として全幅で入る:帯を差し込むと、表示と操作の段のあいだに全幅で入ります。このとき、帯の単位と、盤のいまとみなす許容差(「いま」からこれだけ以内なら実時間として扱う、という値)の単位をそろえます。帯が分で動いているのに、盤の側がミリ秒のままだと、実時間の判定が黙ってずれます。
禁止パターン:速さを連続の倍率にすること。読み手は倍率を暗算し、しかも同じ速さに戻せません。
7. パターン集(Good / Bad / How to fix)
7.0 よく崩れる設計パターン(5つ)
- 速さが連続の倍率:いま何倍かは読めても、それが何を意味するか暗算になり、同じ速さに戻せません
- 「いまへ戻る」が無い:一度動かすと、現在位置に戻る手順が読み手に分かりません
- 状態を大きい表示の色で示している:コントラストの基準に届かず、色覚特性でも伝わりません
- 飛ばしのボタンの文字に向きを書いている:4 つ並ぶと、押す前に読む文字が増えます
- 触れるボタンが小さい:繰り返し押すボタンなので、外すたびに操作がやり直しになります
7.1 Bad(典型5つ)
- 速さがつまみで、目盛りに「1 倍」から「10,000,000 倍」まで書かれている
- 3 時間前まで戻ったあと、現在に戻るには時刻の入力欄を開いて今日の時刻を打ち直す
- いまから外れると、大きい時刻の文字色が薄い黄色に変わる。札は出ていない
- 飛ばしのボタンの文字が「1 時間前へ」「1 時間後へ」で、4 つ並ぶと読む文字が多い
- 再生ボタンの高さが 28 ピクセルで、繰り返し押すと外す
7.2 Good(対になる5つ)
- 速さを「1 秒 / 秒」「1 分 / 秒」「10 分 / 秒」「1 時間 / 秒」「1 日 / 秒」の 5 段にする
- 「いまへ戻る」を常に置き、実時間にいるあいだは押せない状態にする
- 大きい時刻は本文と同じ色のまま、状態は札が「いまではない」と文字で言う
- 飛ばしのボタンの文字を「1 時間」「1 日」にして、向きはアイコンに持たせる
- 触れるボタンの高さを 44 ピクセルにそろえる
7.3 How to fix(手順)
- 速さの連続値をやめ、その画面で実際に使う段を 3 つから 5 つ選ぶ
- 段に名前を付ける。倍率ではなく「1 時間 / 秒」のように、1 秒で何進むかを書く
- 「いまへ戻る」を置き、実時間のあいだは押せない状態にする
- 飛ばしのボタンの文字から向きの語を外し、アイコンと並びの左右に任せる
- 大きい表示の色を本文色に戻し、状態を札の文字に移す
- 触れるボタンの高さを 44 ピクセルにそろえる
- 渡していない操作が画面に出ていないか確かめる
8. ルール(Must / Better)
Must(守らないと壊れる)
Better(品質が跳ねる)
9. アクセシビリティ要件(必須)
この操作盤は、押すものが 4 種類(速さ、飛ばし、再生、いまへ戻る)並ぶコンポーネントです。読み上げで崩れるのは「押下状態が届かない」「ボタンの文字から向きが読めない」「状態が色だけ」の 3 つです(9.1 と 9.3)。ほかにキーボード(9.2)、タッチ(9.4)、動き(9.5)の要件があります。
9.1 Screen Reader
<div class="transport" role="group" aria-label="時間の操作">
<p class="transport__value" aria-live="off">
<strong>07:00:00</strong>
<span class="transport__badge">いまではない</span>
</p>
<p class="transport__secondary">2026-09-12 JST</p>
<!-- 向きはアイコン、読み上げには向きと幅の両方を渡す -->
<button type="button" aria-label="戻る 1 時間">
<svg aria-hidden="true" focusable="false"><polygon points="9,1 9,11 2,6" /></svg>
<span>1 時間</span>
</button>
<!-- 再生は押下状態を持つ -->
<button type="button" aria-pressed="true" aria-label="再生">
<svg aria-hidden="true" focusable="false"><rect x="2" y="1" width="3" height="10" /></svg>
</button>
<!-- 押せないときは、理由が分かる語を添える -->
<button type="button" disabled>いまへ戻る(いまを表示中)</button>
</div>
見た目ではボタンの文字から向きの語を外しますが、読み上げには向きと量の両方を渡します。音では並びの左右もアイコンも届かないためです。見えている文字(「1 時間」)と読み上げの文字(「戻る 1 時間」)が違ってよいのは、後者が前者を含んでいるからです。
大きい時刻の表示を、自動で読み上げさせないようにします(上の例では aria-live="off" を明示しています)。再生中は毎秒変わるので、読み上げが時刻だけで埋まります。位置が変わったことを知らせたいなら、操作が終わった時点で 1 回だけ知らせます。
9.2 Keyboard
- 読む順を、表示、飛ばし、再生、いまへ戻る、速さ、の順にします。先頭の表示は押せないので、タブ移動の対象にはしません(いまどこを映しているかを先に読ませるために、読み上げの順で前に置きます)。タブで移る対象は飛ばし、再生、いまへ戻る、速さの 4 つで、押す頻度の高いものを先にします。速さが最後なのは、一度選んだらしばらく変えないためです
- 再生の切り替えは Space と Enter の両方で動くようにします(
<button>を使えば既定で動きます) - 速さの段は Toggle Group と同じ扱いにして、左右の矢印で段を移れるようにします
- 押せない状態のボタンは、押せないことが分かる見た目にします。タブ移動から外すかどうかは、その盤で押せるようになる見込みがあるかで決めます。「いまへ戻る」は実時間から外れればすぐ押せるようになるので、外さないほうが読み手は見つけられます
9.3 色だけに頼らない
- 状態は札の文字:実時間かどうかを、大きい表示の色で示さないようにします
- 再生中は形も変える:色の反転だけでなく、アイコンを一時停止の形に替えます
- 押せない状態を、薄さだけで示さない:薄く見せるなら
disabledも付け、押せない理由が分かる語を添えます - コントラスト:大きい表示の文字は本文と同じ基準(4.5:1 以上)で読めるようにします。意味を示す 3 色を薄い面の上に文字色として置くと、この基準に届きません
9.4 Touch / Pointer
- 再生、飛ばし、いまへ戻るの高さを 44 ピクセル以上にします
- 飛ばしのボタンが 4 つ並ぶので、隣との間隔を 8 ピクセル以上空けます。繰り返し押すボタンが密に並ぶと、隣を押します
- 掴んで動かす面を差し込む場合、その面の縦スクロールを止めないようにします。詳しくは Day Band の 9.4 を参照してください
9.5 Motion
再生中は画面の値が動き続けます。動きを減らす設定を入れている読み手には、再生そのものを止めるのではなく、再生の周辺の演出(つまみの滑り、数字のスライド)を止めます。値が動くことは読み手が選んだ操作の結果なので、それ自体は残します。
10. 実装メモ(Implementation Notes)
- GUNJO の
TimeTransportは、位置を数(エポックミリ秒、フレーム番号、刻みの数)として受け取ります。単位はコンポーネントが知りません - 速さの段は
{ value, label }の配列で渡します。名前は呼び出し側が付けます - 飛ばしの量は符号付きで渡します。負の側が戻る向きで、左右の振り分けとアイコンはコンポーネントが担当します
- 実時間かどうかは
liveで直接渡せます。nowからの距離で判定させたい場合は、いまとみなす許容差を渡します。このとき、掴んで動かす面の単位とそろえます - 「いまへ戻る」を押したときの動きは差し替えられます。既定は位置を「いま」に戻すだけなので、再生の停止や追従の再開もしたい場合は自分で書きます
- 時間を進める仕組みは操作盤の中にありません。位置を進めるのは呼び出し側です。いまの時刻を描画中に読まないようにします
- 実装は GUNJO の TimeTransport(gunjo.jp を新しいタブで開く) にあります。実時間、いまから外れている、再生中、飛ばしなし、操作できない形の見本が置かれています
- 実時間の札は Live Badge が描いています。同じ形を 2 か所に作らないための分け方です
11. 関連リンク
- 関連するUIデザイン原則: ユーザーコントロール (User Control), 状態の可視化 (Visibility of System Status), 取り消しとやり直し (Undo / Redo), Fittsの法則とタッチターゲット (Fitts's Law)
- 用語集(定義): システム状態の可視性 (Visibility of System Status), 取り消しとやり直し (Undo / Redo), 認識より再認 (Recognition over Recall)
- 関連するUIコンポーネント(横): Day Band(いちにちの帯), Live Badge(LIVEの札), Slider(スライダー)
12. まとめ
この操作盤の設計でいちばん効くのは、速さを名前のついた段にすることです。迷ったら 4. 設計判断の核 に戻ってください。とくに効く 4 つはこれです。「速さに名前が付いているか」「ひと押しで『いま』へ戻れるか」「向きをアイコンに持たせているか」「状態を色だけに載せていないか」を確かめます。
倍率のつまみは、作る側には自然に見えます。読み手が受け取るのは数字だけで、それが 1 秒で何進むのかは暗算になり、気に入った速さに戻ることもできません。段に名前を付けると、選ぶことと戻ることが同時にできるようになります。そして時間を動かせる画面は読み手を迷子にするので、脱出口を 1 つ、常に押せる場所に置いておきます。