Webパーツ辞典

コーチマークCoach mark

初めて使う人に、画面の部品を1つずつ指して説明する案内。周りを暗くして対象だけを明るく残し、「1 / 3」「次へ」「スキップ」の小窓を添える。

表示例

記事の一覧

アイコン: Font Awesome 7 Free(fa-solid / fa-regular)

別名・英語表記

  • 製品ツアー
  • オンボーディングツアー
  • 操作ガイド
  • ウォークスルー
  • 使い方ツアー
  • Tour
  • Coach mark

実装例

<div class="x-coach-mark">
  <!-- 外枠は画面の一部を切り取った見本。実際は案内したい要素に anchor-name を付け、吹き出しをアンカー配置で重ねる
       (位置を測るのはアンカー配置に対応しない版だけ) -->
  <div class="x-coach-mark__app">
    <p class="x-coach-mark__title">記事の一覧</p>
    <button class="x-coach-mark__tool" type="button" aria-label="検索">
      <i class="fa-solid fa-magnifying-glass" aria-hidden="true"></i>
    </button>
    <button class="x-coach-mark__tool x-coach-mark__tool--on" type="button">
      <i class="fa-solid fa-bookmark" aria-hidden="true"></i>保存
    </button>
  </div>
  <!-- 背後の操作を止めるなら showModal() で開く。見本では aria-modal を付けていない -->
  <div class="x-coach-mark__tip" role="dialog" aria-labelledby="x-coach-mark-t" aria-describedby="x-coach-mark-d">
    <p class="x-coach-mark__step">手順 1 / 3</p>
    <p class="x-coach-mark__t" id="x-coach-mark-t">気になる記事を保存</p>
    <p class="x-coach-mark__d" id="x-coach-mark-d">ここを押すと、あとで読むリストに入ります。</p>
    <div class="x-coach-mark__act">
      <button class="x-coach-mark__skip" type="button">スキップ</button>
      <button class="x-coach-mark__next" type="button">次へ</button>
    </div>
  </div>
</div>

AIへの指示文

「コーチマーク(Coach mark)」を実装してください。

## これは何か
初めて使う人に、画面の部品を1つずつ指して説明する案内。周りを暗くして対象だけを明るく残し、「1 / 3」「次へ」「スキップ」の小窓を添える。

## 使いどころ
- 新しい機能を出したときに、その置き場所を1回だけ知らせたいとき
- 初めてログインした人に、主要な操作を2〜4か所だけ案内したいとき

## 実装の要件
- 案内する要素に JavaScript で style.anchorName = "--coach" を付け、前の手順の要素からは外す(同じ名前が複数あると、ソース順で最後の要素に付く)
- 小窓は position: fixed; position-anchor: --coach; position-area: block-end; justify-self: anchor-center; で対象の下に中央をそろえて置く(Chrome・Edge は 130 から、Safari は 26 から、Firefox は 147 から)
- 下が足りないときの上への反転は、小窓の position-try-fallbacks: flip-block; でブラウザに任せる。小窓はスクロールしても対象に付いてくる。アンカー配置で置くときは、参考実装の矢印(::before)は反転に付いてこないので出さない
- 1語の block-end は Chrome・Edge 143 以前と Firefox 147 で小窓を画面の横へはみ出させる。justify-self: anchor-center で防ぎ、place-self は使わない(縦にも効き、Chrome・Edge 139 以前は空きがあっても上に出るか対象に重なり、Firefox 147 は対象から離れる)
- 小窓の margin は margin: 14px 0 0; のように auto を含まない値にする。参考実装の margin: 14px 10px 0 auto も、dialog 要素や popover 属性の既定の margin: auto も、古い版で小窓を対象から離す
- 小窓を dialog 要素や popover 属性で作るなら inset: auto; を、showModal() で開くなら max-height: none; も足す。既定の inset: 0 は古い版で下に空きがあっても小窓を上へ回し、既定の max-height は小窓を縮めて上へ反転させない
- CSS.supports("position-area", "block-end") が false の版だけ、対象の getBoundingClientRect() から小窓の top と left を決めて下に重ね、下が足りなければ上に置く。スクロールとリサイズのたびに測り直す
- 暗幕は画面全体の半透明の膜にし、対象の部分だけを抜く(box-shadow を 100vmax まで広げる・clip-path など)。対象には枠線も重ねる
- showModal() で開くなら ::backdrop を background: transparent にする。既定の ::backdrop が対象ごと画面全体を覆い、対象だけを明るく残せない
- 手順は配列で持ち、「次へ」「スキップ」で進める。見終えたかどうかは localStorage などに保存する
- 手順を増やしすぎない。長いツアーは読まずにスキップされる。案内がないと使えない画面なら、画面の側を直す
- スキップの手段を最初の手順から出す。最後まで見ないと抜けられない案内にしない
- 見終えた人・スキップした人に毎回出さない。見終えたことを保存し、ヘルプからもう一度見られるようにする
- 案内する要素が画面の外にあると、小窓が宙に浮く。出す前にその要素を画面内へスクロールする

## アクセシビリティの要件
- 小窓は role="dialog" にし、見出しと本文を aria-labelledby / aria-describedby で結ぶ。開いたら小窓の中へフォーカスを移す
- 背後を暗くして操作を止めるなら showModal() で開く(背後の inert はブラウザが持つ)。止めないなら非モーダルにして、Tab で小窓と画面を行き来できるようにする
- Esc で案内を終えられるようにし、終えたら元の場所へフォーカスを戻す
- 小窓がフォーカスしている要素を覆い隠さないようにする(WCAG 2.2 の 2.4.11 隠されないフォーカス(最低限))
- 何番目かを「手順 1 / 3」のように文字で書く。点の列だけで示さない

## 参考にする実装
この形を出発点にして、プロジェクトの命名規則・色・余白に合わせて調整してください。

```html
<div class="x-coach-mark">
  <!-- 外枠は画面の一部を切り取った見本。実際は案内したい要素に anchor-name を付け、吹き出しをアンカー配置で重ねる
       (位置を測るのはアンカー配置に対応しない版だけ) -->
  <div class="x-coach-mark__app">
    <p class="x-coach-mark__title">記事の一覧</p>
    <button class="x-coach-mark__tool" type="button" aria-label="検索">
      <i class="fa-solid fa-magnifying-glass" aria-hidden="true"></i>
    </button>
    <button class="x-coach-mark__tool x-coach-mark__tool--on" type="button">
      <i class="fa-solid fa-bookmark" aria-hidden="true"></i>保存
    </button>
  </div>
  <!-- 背後の操作を止めるなら showModal() で開く。見本では aria-modal を付けていない -->
  <div class="x-coach-mark__tip" role="dialog" aria-labelledby="x-coach-mark-t" aria-describedby="x-coach-mark-d">
    <p class="x-coach-mark__step">手順 1 / 3</p>
    <p class="x-coach-mark__t" id="x-coach-mark-t">気になる記事を保存</p>
    <p class="x-coach-mark__d" id="x-coach-mark-d">ここを押すと、あとで読むリストに入ります。</p>
    <div class="x-coach-mark__act">
      <button class="x-coach-mark__skip" type="button">スキップ</button>
      <button class="x-coach-mark__next" type="button">次へ</button>
    </div>
  </div>
</div>
```

```css
/* 貼った先のリセットに頼らないよう、この部品の中だけ border-box にする */
.x-coach-mark,
.x-coach-mark *:not([class*="fa-"]),
.x-coach-mark *:not([class*="fa-"])::before,
.x-coach-mark *:not([class*="fa-"])::after {
  box-sizing: border-box;
  /* 貼った先の既定の書体に引きずられないようにする。書体が変わると
     文字の幅と高さが変わり、枠のサイズまでずれる */
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Hiragino Sans", "Noto Sans JP", "Yu Gothic UI", Meiryo, sans-serif;
}

/* 暗幕を外枠の中に閉じ込めるため overflow: hidden。実際の暗幕は画面全体を覆う */
.x-coach-mark {
  position: relative;
  width: 320px;
  max-width: 100%;  /* 狭い画面では親の幅に合わせて縮む */
  padding-bottom: 14px;
  border: 1px solid #e3e6ea;
  border-radius: 10px;
  background: #f3f4f6;
  overflow: hidden;
}
.x-coach-mark__app {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  border-bottom: 1px solid #e3e6ea;
  background: #fff;
}
.x-coach-mark__title {
  flex: 1;
  margin: 0;
  color: #1b2028;
  font-size: 13px;
  font-weight: 700;
}
.x-coach-mark__tool {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 36px;
  min-height: 36px;
  padding: 0 10px;
  border: 1px solid #7f8a99;
  border-radius: 8px;
  background: #fff;
  color: #1b2028;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
/* 案内している要素だけを暗幕からくり抜く。広げた影が暗幕の代わりになる。
   白い枠も重ねて、暗幕の濃さに頼らず位置を示す */
.x-coach-mark__tool--on {
  position: relative;
  z-index: 1;
  outline: 3px solid #fff;
  outline-offset: 2px;
  box-shadow: 0 0 0 100vmax rgba(15, 23, 42, 0.55);
}
.x-coach-mark__tip {
  position: relative;
  z-index: 2;
  width: 236px;
  margin: 14px 10px 0 auto;
  padding: 12px 14px;
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 8px 20px rgba(15, 23, 42, 0.3);
}
/* 吹き出しの矢印。案内している要素の方向を指す */
.x-coach-mark__tip::before {
  content: "";
  position: absolute;
  top: -7px;
  right: 28px;
  width: 14px;
  height: 14px;
  background: #fff;
  transform: rotate(45deg);
}
.x-coach-mark__step {
  margin: 0 0 4px;
  color: #5b6472;
  font-size: 11px;
}
.x-coach-mark__t {
  margin: 0 0 4px;
  color: #1b2028;
  font-size: 13px;
  font-weight: 700;
}
.x-coach-mark__d {
  margin: 0 0 10px;
  color: #3f4652;
  font-size: 12px;
  line-height: 1.6;
}
.x-coach-mark__act {
  display: flex;
  justify-content: space-between;
  gap: 8px;
}
.x-coach-mark__skip,
.x-coach-mark__next {
  min-height: 32px;
  padding: 0 14px;
  border-radius: 7px;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.x-coach-mark__skip {
  border: 0;
  background: none;
  color: #4b5563;
  text-decoration: underline;
}
.x-coach-mark__next {
  border: 0;
  background: #1d4ed8;
  color: #fff;
  font-weight: 700;
}
.x-coach-mark__tool:focus-visible,
.x-coach-mark__skip:focus-visible,
.x-coach-mark__next:focus-visible {
  outline: 2px solid #1d4ed8;
  outline-offset: 2px;
}
```

## 出力の約束
- HTML と CSS を分けて出す。JavaScript が要るときは素の JavaScript で書き、UIフレームワークは使わない。
- 参考実装がアイコンに Font Awesome のクラスを使っている場合は、プロジェクトで使っているアイコンかインライン SVG に置き換えてよい。
- 上のアクセシビリティ要件を満たす。満たせない箇所があるときは、理由を添えて先に知らせる。
- 色・角丸・余白は既存のデザイントークンがあればそれを使う。無ければ CSS 変数として切り出す。

使いどころ

  • 新しい機能を出したときに、その置き場所を1回だけ知らせたいとき
  • 初めてログインした人に、主要な操作を2〜4か所だけ案内したいとき

注意点

  • 手順を増やしすぎない。長いツアーは読まずにスキップされる。案内がないと使えない画面なら、画面の側を直す
  • スキップの手段を最初の手順から出す。最後まで見ないと抜けられない案内にしない
  • 見終えた人・スキップした人に毎回出さない。見終えたことを保存し、ヘルプからもう一度見られるようにする
  • 案内する要素が画面の外にあると、小窓が宙に浮く。出す前にその要素を画面内へスクロールする

アクセシビリティの要点

  • 小窓は role="dialog" にし、見出しと本文を aria-labelledby / aria-describedby で結ぶ。開いたら小窓の中へフォーカスを移す
  • 背後を暗くして操作を止めるなら showModal() で開く(背後の inert はブラウザが持つ)。止めないなら非モーダルにして、Tab で小窓と画面を行き来できるようにする
  • Esc で案内を終えられるようにし、終えたら元の場所へフォーカスを戻す
  • 小窓がフォーカスしている要素を覆い隠さないようにする(WCAG 2.2 の 2.4.11 隠されないフォーカス(最低限))
  • 何番目かを「手順 1 / 3」のように文字で書く。点の列だけで示さない

作るときに使えるツール

関連するパーツ