JavaScript Tips | UI・画面部品:Toastを表示する

JavaScript JavaScript
スポンサーリンク
スポンサーリンク

Toastを表示するユーティリティは「ユーザーにさりげなく“結果”を伝えるための仕組み」です

業務システムやWebアプリケーションでは、 ユーザーの操作に対して「結果」を伝える場面がたくさんあります。

  • 保存が成功した
  • 削除が完了した
  • エラーが発生した
  • 通知が届いた

これらを毎回ダイアログ(Modal)で出してしまうと、 ユーザーは操作のたびに立ち止まらされてしまいます。

そこで活躍するのが Toast(トースト通知) です。

Toastは、

  • 画面の端(右上・左下など)に
  • 数秒だけふわっと表示されて
  • 自動的に消えていく小さな通知

であり、「ユーザーの操作を邪魔せずに結果を伝えるためのUI部品」です。

ここでは、初心者向けに、

  • Toastの基本構造
  • JavaScriptでToastを表示するユーティリティ
  • 業務で使いやすい設計と注意点

をステップバイステップで解説していきます。

ステップ1:Toastの役割とModalとの違いを整理する

まず、Toastがどんな場面で使われるべきか、Modalとの違いを整理します。

Toastの役割

  • 結果の通知
    • 「保存しました」「削除しました」「送信に成功しました」など。
  • 軽いエラーや警告
    • 「一部の項目が保存されませんでした」「ネットワークが不安定です」など。
  • ユーザーの操作を止めない
    • Toastが出ていても、ユーザーは画面操作を続けられます。

Modalとの違い

  • Modal:ユーザーに「判断」や「確認」を求める場
    • 例:「本当に削除しますか?」
  • Toast:ユーザーに「結果」や「状態」を伝える場
    • 例:「削除しました」「保存に失敗しました」

ポイント:Toastは「結果の報告」、Modalは「判断の依頼」という役割の違いがあります。 この違いを意識して使い分けると、UI設計がぐっと分かりやすくなります。

ステップ2:Toastの基本HTML構造を用意する

Toastは、通常「画面の端に積み上がる」形で表示されます。

まずは、Toastを表示するためのコンテナをHTMLに用意します。

HTMLの基本テンプレート

<!-- Toastコンテナ(画面右上に表示する想定) -->
<div id="toast-container" class="toast-container" aria-live="polite" aria-atomic="true">
  <!-- ここにJavaScriptでToast要素を追加していきます -->
</div>

ここで重要なのは次の点です。

  • toast-container:Toastをまとめて表示するためのコンテナ
  • aria-live="polite":スクリーンリーダーに「ここに新しいメッセージが出るよ」と伝える属性
  • aria-atomic="true":メッセージをまとめて読み上げるための属性

アクセシビリティを意識すると、 Toastは「視覚的な通知」だけでなく「音声読み上げの通知」としても機能します。

ステップ3:CSSでToastの見た目と位置を整える

次に、Toastの見た目と表示位置をCSSで定義します。

例:右上に表示されるToastのCSS

.toast-container {
  position: fixed;
  top: 16px;
  right: 16px;
  z-index: 2000;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.toast {
  min-width: 240px;
  max-width: 320px;
  background: #333;
  color: #fff;
  padding: 12px 16px;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
  font-size: 14px;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.toast.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.toast--success {
  background: #2e7d32; /* 緑系 */
}

.toast--error {
  background: #c62828; /* 赤系 */
}

.toast--info {
  background: #1565c0; /* 青系 */
}

.toast-message {
  flex: 1;
}

.toast-close {
  background: transparent;
  border: none;
  color: inherit;
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
}

ここでは、

  • .toast-container を画面右上に固定
  • .toast を小さなカード風に表示
  • .toast.is-visible でフェードイン・スライドインのアニメーション
  • .toast--success / .toast--error / .toast--info で種類ごとの色分け

という構造にしています。

ポイント:Toastは「目立ちすぎず、でも一目で種類が分かる」デザインにすることが大事です。 成功・エラー・情報などを色で分けると、ユーザーが直感的に理解しやすくなります。

ステップ4:JavaScriptでToast要素を生成・表示するユーティリティを作る

いよいよ、JavaScriptでToastを表示するユーティリティを作っていきます。

基本ユーティリティ

export const Toast = {
  _container: null,

  _ensureContainer() {
    if (this._container) return;

    const el = document.getElementById("toast-container");
    if (el) {
      this._container = el;
      return;
    }

    // コンテナが存在しない場合は動的に作成する
    const newEl = document.createElement("div");
    newEl.id = "toast-container";
    newEl.className = "toast-container";
    newEl.setAttribute("aria-live", "polite");
    newEl.setAttribute("aria-atomic", "true");
    document.body.appendChild(newEl);
    this._container = newEl;
  },

  show(message, options = {}) {
    this._ensureContainer();

    const {
      type = "info",      // "success" | "error" | "info"
      duration = 3000,    // 表示時間(ミリ秒)
      closable = true,    // 閉じるボタンを表示するか
    } = options;

    const toastEl = document.createElement("div");
    toastEl.classList.add("toast");

    // 種類に応じてクラスを付与
    if (type === "success") {
      toastEl.classList.add("toast--success");
    } else if (type === "error") {
      toastEl.classList.add("toast--error");
    } else {
      toastEl.classList.add("toast--info");
    }

    // メッセージ部分
    const messageEl = document.createElement("div");
    messageEl.className = "toast-message";
    messageEl.textContent = message;
    toastEl.appendChild(messageEl);

    // 閉じるボタン
    if (closable) {
      const closeBtn = document.createElement("button");
      closeBtn.className = "toast-close";
      closeBtn.type = "button";
      closeBtn.setAttribute("aria-label", "閉じる");
      closeBtn.textContent = "×";
      closeBtn.addEventListener("click", () => {
        this._hide(toastEl);
      });
      toastEl.appendChild(closeBtn);
    }

    // コンテナに追加
    this._container.appendChild(toastEl);

    // 少し遅らせて is-visible を付けてアニメーション
    requestAnimationFrame(() => {
      toastEl.classList.add("is-visible");
    });

    // 自動で消す
    if (duration > 0) {
      setTimeout(() => {
        this._hide(toastEl);
      }, duration);
    }

    return toastEl;
  },

  _hide(toastEl) {
    toastEl.classList.remove("is-visible");
    // アニメーション終了後にDOMから削除
    setTimeout(() => {
      if (toastEl.parentNode) {
        toastEl.parentNode.removeChild(toastEl);
      }
    }, 200); // CSSのtransition時間と合わせる
  },
};
JavaScript

使用例

// 保存成功時
Toast.show("保存が完了しました。", { type: "success", duration: 3000 });

// エラー時
Toast.show("保存に失敗しました。ネットワーク状態を確認してください。", {
  type: "error",
  duration: 5000,
});

// 情報通知
Toast.show("新しい通知があります。", { type: "info", duration: 4000 });
JavaScript

ポイント:Toastユーティリティは「メッセージと種類を渡すだけで表示できる」ようにしておくと、 どの画面からでも簡単に使えるようになります。

ステップ5:業務でよくある「成功・エラー・警告」のToastテンプレート

業務システムでは、Toastの種類をある程度決めておくと使いやすくなります。

成功Toast

export function showSuccessToast(message) {
  Toast.show(message, {
    type: "success",
    duration: 3000,
  });
}
JavaScript

エラーToast

export function showErrorToast(message) {
  Toast.show(message, {
    type: "error",
    duration: 5000,
  });
}
JavaScript

情報Toast

export function showInfoToast(message) {
  Toast.show(message, {
    type: "info",
    duration: 4000,
  });
}
JavaScript

使用例

// 保存成功
showSuccessToast("設定を保存しました。");

// 保存失敗
showErrorToast("設定の保存に失敗しました。時間をおいて再度お試しください。");

// 情報
showInfoToast("新しいバージョンが利用可能です。");
JavaScript

ポイント:種類ごとのラッパー関数を用意しておくことで、 チーム全体で「どの場面でどのToastを使うか」を統一しやすくなります。

ステップ6:Toastの「多重表示」と「積み上げ方」をどう設計するか(重要な深掘り)

Toastは、短時間に複数表示されることがあります。

  • ユーザーが連続して保存操作を行った
  • バッチ処理で複数の結果が返ってきた
  • エラーが連続して発生した

このとき、次のような設計ポイントがあります。

1. Toastは「積み上げる」か「最新だけにする」か

  • 積み上げる方式
    • すべてのToastを表示し、コンテナ内に縦に並べる。
    • ユーザーは過去のメッセージも確認できる。
  • 最新だけにする方式
    • 既存のToastを消してから新しいToastを表示する。
    • 画面がすっきりするが、過去のメッセージは見られない。

業務システムでは、

  • エラーや重要なメッセージは「積み上げる」
  • 軽い情報通知は「最新だけにする」

など、種類ごとに方針を分けるのも一つの手です。

2. 多すぎるToastをどう扱うか

  • 短時間に大量のToastが出ると、画面が通知だらけになってしまいます。
  • その場合は「最大表示数」を決めておき、 古いToastから順に消す設計も考えられます。

最大表示数を制限する例

export const Toast = {
  _container: null,
  _maxCount: 5,

  // ...前述の _ensureContainer など...

  show(message, options = {}) {
    this._ensureContainer();

    // 既存のToastが多すぎる場合は古いものから削除
    const existingToasts = this._container.querySelectorAll(".toast");
    if (existingToasts.length >= this._maxCount) {
      const oldest = existingToasts[0];
      this._hide(oldest);
    }

    // 以下は前述の show と同じ
  },

  // ...
};
JavaScript

ポイント:Toastは「さりげない通知」なので、 多すぎて画面を占領してしまわないように、数や表示時間を設計することが重要です。

ステップ7:セキュリティ・プライバシーの観点からの注意点

Toastは画面上に表示されるため、 「誰が画面を見ているか」によっては、情報漏洩の一因になり得ます。

注意すべき点

  • Toastに機密情報(パスワード、トークン、個人情報など)を表示しない。
  • エラーメッセージに内部構造(SQL文、スタックトレースなど)をそのまま表示しない。
  • 「このユーザーは管理者です」など、権限情報を過度に表示しない。

安全なメッセージの例

  • 「保存に失敗しました。時間をおいて再度お試しください。」
  • 「権限が不足しているため、この操作は実行できません。」

ポイント:Toastは「誰の目にも触れやすい」情報なので、 セキュリティ・プライバシーの観点から、表示内容を慎重に設計する必要があります。

ステップ8:チームで共有するための「Toast設計ルール」をコードとドキュメントに刻む

コードコメントで明示する

// 注意:
// Toastは、ユーザーに操作結果や状態をさりげなく伝えるためのUI部品です。
// Toast.show / showSuccessToast / showErrorToast などのユーティリティを使い、
// メッセージと種類を指定して表示するようにしてください。
// Toastには機密情報(パスワード、トークン、個人情報など)を表示しないでください。
// 短時間に大量のToastを表示しないように、最大表示数や表示時間を適切に設定してください。
JavaScript

レビュー時のチェックポイント

  • 成功・エラー・情報などのToastが、ユーティリティ経由で表示されているか
  • Toastのメッセージに機密情報が含まれていないか
  • Toastの表示位置・デザインが一貫しているか
  • Toastがユーザーの操作を邪魔していないか(Modalと混同されていないか)

こうしたルールをチームで共有することで、 「画面ごとにバラバラな通知」「危険なメッセージ表示」などの問題を防ぎやすくなります。

まとめ:Toastを表示するユーティリティは「ユーザーにさりげなく結果を伝え、操作の流れを止めないための実務的なUI技術」です

Toastを表示するためのJavaScriptユーティリティと設計を導入することで、次のような効果があります。

  • どの画面でも同じスタイルで通知を出せる
  • 成功・エラー・情報などを、色と位置で分かりやすく伝えられる
  • ユーザーの操作を止めずに、結果だけをスマートに知らせられる
  • チーム全体で「通知の出し方」を統一し、セキュリティ・プライバシーにも配慮できる

業務システムにおいて、Toastは「ユーザーとの対話の質」を高める重要な部品です。

そのToastを、きちんとしたユーティリティと設計で扱うことは、 ユーザー体験とシステムの信頼性を両立させるうえで、とても実務的で重要な技術だと言えます。

タイトルとURLをコピーしました