WithCodeMedia-1-pc
previous arrowprevious arrow
next arrownext arrow

WithCodeMedia-1-sp
previous arrowprevious arrow
next arrownext arrow

CSSツールチップの作り方|補足説明を吹き出しで出すコピペ集

生徒

用語の横に「?」を置いて、カーソルを乗せたら説明が出るやつを作りたいです。

ペン博士

ツールチップだね。擬似要素とdata属性だけで作れるよ。位置調整と、スマホやキーボードへの配慮までまとめて渡すね。

専門用語の補足、アイコンの意味、入力欄のヒント。画面を圧迫せずに情報を足せるのがツールチップです。

実装はシンプルで、data-*属性に文言を入れ、::afterで表示するだけ。JavaScriptもライブラリも要りません。

この記事では基本形から、4方向の位置指定、三角形の付け方、はみ出し対策、タッチ端末とキーボードへの対応まで解説します。

  • ツールチップの基本構造(data属性+擬似要素)
  • 上下左右4方向の出し分け
  • 三角形(しっぽ)を付ける方法
  • フェードインなど表示アニメーション
  • 長文を折り返して表示する
  • 画面端ではみ出さないようにする
  • タッチ端末・キーボードへの対応
  • title属性との違いと使い分け
  • 表示されないときの原因と対処
  • コピペで使える完成版

目次

ツールチップの基本構造

吹き出しが出る仕組み

文言はHTMLのdata-tip属性に持たせ、CSSのattr()で取り出して表示します。

<p>
  この処理は
  <span class="tip" data-tip="ブラウザが表示を組み立て直すこと。頻発すると重くなります。">
    リフロー
  </span>
  を発生させます。
</p>
.tip {
  position: relative;         /* 吹き出しの基準 */
  border-bottom: 1px dotted #6b7280;
  cursor: help;
}

.tip::after {
  content: attr(data-tip);    /* 属性の値をそのまま表示 */
  position: absolute;
  bottom: calc(100% + 10px);  /* 要素の上に出す */
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  max-width: 260px;
  padding: 10px 14px;
  border-radius: 8px;
  background-color: #1f2937;
  color: #fff;
  font-size: 0.85rem;
  line-height: 1.6;
  text-align: left;
  opacity: 0;
  visibility: hidden;
  transition: opacity .2s, visibility .2s;
  z-index: 50;
}

.tip:hover::after,
.tip:focus-visible::after {
  opacity: 1;
  visibility: visible;
}

width: max-contentmax-widthの組み合わせが要点です。短い文は1行、長い文は折り返すという自然な挙動になります。

上下左右4方向の出し分け

出す方向の選び方

配置場所に応じて出す方向を変えられるよう、クラスで切り替えます。

/* 上(既定) */
.tip.-top::after {
  bottom: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%);
}

/* 下 */
.tip.-bottom::after {
  top: calc(100% + 10px);
  bottom: auto;
  left: 50%;
  transform: translateX(-50%);
}

/* 左 */
.tip.-left::after {
  right: calc(100% + 10px);
  left: auto;
  bottom: auto;
  top: 50%;
  transform: translateY(-50%);
}

/* 右 */
.tip.-right::after {
  left: calc(100% + 10px);
  bottom: auto;
  top: 50%;
  transform: translateY(-50%);
}

基本は上方向です。ページ最上部の要素や、ヘッダー内のアイコンでは下方向に切り替えます。表の右端では左方向、というように配置場所で選びます。

三角形(しっぽ)を付ける

吹き出しらしくするには、::beforeで小さな三角を描いて本体につなげます。

.tip::before {
  content: "";
  position: absolute;
  bottom: calc(100% + 4px);
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: #1f2937;   /* 本体と同じ色 */
  opacity: 0;
  visibility: hidden;
  transition: opacity .2s, visibility .2s;
  z-index: 51;
}

.tip:hover::before,
.tip:focus-visible::before {
  opacity: 1;
  visibility: visible;
}

/* 下方向のときは三角も反転 */
.tip.-bottom::before {
  bottom: auto;
  top: calc(100% + 4px);
  border-top-color: transparent;
  border-bottom-color: #1f2937;
}

三角形は幅と高さ0の要素にborderを当てて作ります。4辺のうち1辺だけ色を付け、残りを透明にすると三角に見えます。

フェードインなど表示アニメーション

出現に動きを付けると、視線が自然に誘導されます。移動距離は小さく保ちます。

.tip::after {
  transform: translateX(-50%) translateY(6px);
  transition: opacity .18s ease, transform .18s ease, visibility .18s;
}

.tip:hover::after,
.tip:focus-visible::after {
  transform: translateX(-50%) translateY(0);
}

/* 表示までの待ち時間を入れると誤爆が減る */
.tip::after,
.tip::before {
  transition-delay: .25s;
}

@media (prefers-reduced-motion: reduce) {
  .tip::after,
  .tip::before {
    transition: none;
  }
}

transition-delayを0.2〜0.3秒入れると、カーソルが通過しただけで開く「誤爆」が減ります。文章中に複数のツールチップがある場合は特に効果的です。

長文を折り返して表示する

説明が長い場合は幅の上限を決め、行間を広めに取ります。表示位置も本体の上ではなく、余白のある方向へ寄せます。

.tip.-wide::after {
  max-width: 320px;
  white-space: normal;      /* 折り返しを許可 */
  line-height: 1.7;
  padding: 12px 16px;
}

/* 改行を入れたい場合はdata属性に改行文字を含める */
.tip.-pre::after {
  white-space: pre-line;
}
<span class="tip -pre" data-tip="1行目の説明です。
2行目はこう書きます。">用語</span>

white-space: pre-lineを使うと、data属性内の改行がそのまま反映されます。箇条書き風の補足を出したいときに便利です。

画面端ではみ出さないようにする

画面の左右端にある要素では、中央揃えのままだと吹き出しが切れます。端の要素だけ基準をずらします。

/* 左端用:左を基準にする */
.tip.-align-start::after {
  left: 0;
  transform: none;
}

/* 右端用:右を基準にする */
.tip.-align-end::after {
  left: auto;
  right: 0;
  transform: none;
}

/* 親のはみ出し切り取りを避ける */
.table-wrap {
  overflow-x: auto;         /* 表の横スクロールは必要 */
}

.table-wrap .tip::after {
  position: fixed;          /* 切り取られたくない場合の回避策 */
}

表の中で使う場合は要注意です。overflow: autoの親を持つと吹き出しが切れます。切れて困る場面では表示方向を内側に向けるのが最も確実です。

タッチ端末・キーボードへの対応

スマホ・キーボード対応

:hoverだけに頼ると、スマホの利用者には情報が届きません。3つの手当てをします。

/* 1. キーボードでも開く */
.tip {
  /* HTML側で tabindex="0" を付けておく */
}

.tip:focus-visible {
  outline: 2px solid #0ea5e9;
  outline-offset: 2px;
}

.tip:focus-visible::after,
.tip:focus-visible::before {
  opacity: 1;
  visibility: visible;
}

/* 2. タッチ端末ではタップで開く(:focusを利用) */
@media (hover: none) {
  .tip:focus::after,
  .tip:focus::before {
    opacity: 1;
    visibility: visible;
  }
}
<span class="tip" tabindex="0" role="note"
      data-tip="ブラウザが表示を組み立て直すこと。">リフロー</span>
  • tabindex="0"を付けてフォーカス可能にする
  • 重要な情報はツールチップに入れず、本文に書く
  • @media (hover: none)でタッチ端末の挙動を分ける
  • 読み上げに乗せたい場合はaria-describedbyで別要素を参照させる

原則として、ツールチップは無くても意味が通る補足に限定します。価格や注意事項など読まれるべき情報を隠すと、届かない利用者が出ます。

title属性との違いと使い分け

HTMLのtitle属性でも似た表示は出せますが、制御できる範囲が違います。

項目title属性CSSツールチップ
見た目変更できない自由に設計できる
表示速度1秒ほど待つ即時〜任意の遅延
スマホほぼ表示されないタップで対応可能
読み上げ環境により読まれる設計次第
実装量属性1つCSSが必要

簡易な補足ならtitleで十分です。デザインを合わせたい、スマホでも見せたい場合はCSSで作ります。両者を併用すると二重に表示されるため、片方に統一してください。

表示されないときの原因と対処

出ない時の原因

動かない場合、原因はほぼ次の6つです。

症状原因対処
何も出ないcontentの指定漏れcontent: attr(data-tip)を確認
位置がページ左上に出る親にpositionがない.tiprelative
途中で切れる親のoverflow方向を内側に変える
他の要素の下に隠れる重なり順が低いz-indexを上げる
文字が1行で伸び続ける折り返し設定がないmax-widthを指定
スマホで出ない:hover依存tabindex:focus

2番目は擬似要素全般で頻発します。position: absoluteの基準は「最も近い位置指定済みの祖先」なので、親側の指定を忘れると想定外の場所へ飛びます。

コピペで使える完成版

方向切り替えとキーボード対応を含んだ一式です。

.tip {
  position: relative;
  border-bottom: 1px dotted #6b7280;
  cursor: help;
}

.tip::after,
.tip::before {
  opacity: 0;
  visibility: hidden;
  transition: opacity .18s ease, transform .18s ease, visibility .18s;
  transition-delay: .25s;
  pointer-events: none;
}

.tip::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%) translateY(6px);
  width: max-content;
  max-width: 260px;
  padding: 10px 14px;
  border-radius: 8px;
  background-color: #1f2937;
  color: #fff;
  font-size: 0.85rem;
  line-height: 1.6;
  text-align: left;
  white-space: normal;
  z-index: 50;
}

.tip::before {
  content: "";
  position: absolute;
  bottom: calc(100% + 4px);
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: #1f2937;
  z-index: 51;
}

.tip:hover::after,
.tip:hover::before,
.tip:focus-visible::after,
.tip:focus-visible::before {
  opacity: 1;
  visibility: visible;
}

.tip:hover::after,
.tip:focus-visible::after {
  transform: translateX(-50%) translateY(0);
}

.tip:focus-visible {
  outline: 2px solid #0ea5e9;
  outline-offset: 2px;
}

@media (hover: none) {
  .tip:focus::after,
  .tip:focus::before {
    opacity: 1;
    visibility: visible;
  }
}

@media (prefers-reduced-motion: reduce) {
  .tip::after,
  .tip::before {
    transition: none;
  }
}

デザインバリエーション5種

配色や形を変えると、サイトのトーンに合わせられます。よく使う5種類を置いておきます。

1. ライトテーマ(白背景・境界線)

.tip.-light::after {
  background-color: #fff;
  color: #1f2937;
  border: 1px solid #e5e7eb;
  box-shadow: 0 8px 24px rgba(15, 23, 42, .12);
}

.tip.-light::before {
  border-top-color: #fff;
}

明るい配色のサイトでは、黒い吹き出しが浮きすぎることがあります。白背景に影を添えると馴染みます。

2. 注意喚起(警告色)

.tip.-warn::after {
  background-color: #b91c1c;
  color: #fff;
  font-weight: 700;
}

.tip.-warn::before {
  border-top-color: #b91c1c;
}

入力エラーの補足など、見落としてほしくない補足に使います。多用すると効果が薄れるため、1画面に1〜2箇所までに留めます。

3. アイコン付きトリガー

.tip.-icon {
  border-bottom: none;
}

.tip.-icon::first-line {
  color: inherit;
}

.tip-mark {
  display: inline-grid;
  place-items: center;
  width: 18px;
  height: 18px;
  margin-left: 4px;
  border-radius: 50%;
  background-color: #94a3b8;
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  vertical-align: middle;
}
<span class="tip -icon" tabindex="0" data-tip="税抜価格です。">
  月額料金<span class="tip-mark">?</span>
</span>

「?」マークを添えると、補足があること自体に気づいてもらえます。マークは装飾なので、読み上げに不要ならaria-hiddenを付けます。

4. 太めの角丸・大きめ文字

.tip.-lg::after {
  padding: 14px 18px;
  border-radius: 14px;
  font-size: 0.95rem;
  max-width: 340px;
}

説明が長い場合や、高齢の利用者が多いサイトでは文字を大きめにします。読みやすさは装飾より優先されます。

5. 遅延なしで即座に出す

.tip.-instant::after,
.tip.-instant::before {
  transition-delay: 0s;
}

管理画面のアイコン群など、次々と確認したい場面では遅延を消します。逆に文章中では遅延ありのほうが快適です。

ツールチップを使う前に考えること

実装より大事なのが「そもそも隠していいのか」という判断です。3つの基準で確認してください。

情報の種類ツールチップ推奨の置き場所
専門用語の意味向くツールチップで補足
アイコンの意味向くラベル併記が理想
価格の条件向かない本文または注記
エラーの理由向かない入力欄の直下に常時表示
操作手順向かない本文で段階的に説明

判断の軸は見なくても困らないかです。見ないと判断を誤る情報は、必ず本文に置きます。

  • 文字数の目安は40〜80字。それ以上は本文へ移す
  • 1画面に5個以上あると読む気が失われる
  • 印刷時には表示されないことを前提にする
  • ページ内検索でヒットしない点も考慮する

実装パターン別・使いどころ早見表

最後に、ここまでのパターンをどの場面で使うか整理しておきます。実装前の判断材料にしてください。

場面推奨パターン理由
記事本文の用語補足上方向・遅延あり読書の流れを妨げない
フォームの入力ヒント右方向・即時入力欄の隣で確認できる
表の中の注記内側方向overflowで切れるのを避ける
ヘッダーのアイコン下方向上に空間がない
スマホ主体のサイトタップ開閉hoverが存在しない

迷ったら上方向・遅延0.25秒・最大幅260pxの基本形で問題ありません。困る場面が出てから方向だけ変える運用が最も手戻りが少なくなります。

/* 基本形を1クラスにまとめておき、必要な時だけ方向クラスを足す */
.tip { position: relative; cursor: help; }
.tip.-bottom::after { top: calc(100% + 10px); bottom: auto; }
.tip.-right::after  { left: calc(100% + 10px); top: 50%; bottom: auto;
                      transform: translateY(-50%); }

方向クラスは後付けで足せる設計にしておくと、ページごとの微調整がCSSの追記だけで済みます。


まとめ

CSSツールチップはdata-tip属性とcontent: attr()の組み合わせで作れます。基準となる要素にposition: relative、吹き出しにabsoluteを指定し、width: max-contentmax-widthで自然な折り返しにするのが要点です。三角形はborderで描き、表示はopacityvisibilityで切り替えるとアニメーションが効きます。タッチ端末ではtabindex="0":focusで開けるようにし、そもそも重要な情報はツールチップに隠さないという設計判断が最も大切です。

よくある質問(FAQ)

data属性に入れたテキストが表示されません。

content: attr(data-tip)の属性名と、HTML側の属性名が一致しているか確認してください。data-tipdata-tooltipのような綴りの違いが原因のことが多いです。また擬似要素はimginputには作れないため、spanなどで包む必要があります。

吹き出しが親要素に切られてしまいます。

親にoverflow: hiddenoverflow: autoがあると擬似要素は切り取られます。表の中などで外せない場合は、吹き出しを内側の方向に出すか、位置をfixedにする回避策を使ってください。

スマホでツールチップを表示するには?

tabindex="0"を付けてタップでフォーカスできるようにし、:focusでも表示されるようにします。@media (hover: none)でタッチ端末だけ挙動を分けると、PCの操作感を保ったまま対応できます。

title属性とどちらを使うべきですか?

見た目を揃えたい、スマホでも見せたい、表示までの待ち時間を短くしたい場合はCSSで作ります。単純な補足で装飾が不要ならtitle属性で十分です。両方指定すると二重に表示されるため、どちらかに統一してください。

ツールチップに重要な情報を入れてもいいですか?

避けてください。マウス操作でしか気づけない、印刷に出ない、読み上げ環境によっては伝わらない、という制約があります。価格や注意事項など必ず読まれるべき内容は本文に書き、ツールチップは補足に限定するのが原則です。

あわせて読みたい関連記事

CSS・Webデザイン実装の総まとめ

CSSの実装テクニックを「レイアウト・装飾・アニメーション・基礎・トラブル解決」の目的別に探せる総まとめページを用意しています。実装で迷ったときの索引としてどうぞ。

AIスキルで、未来の自分をアップデート!

今なら完全無料でAIを学べる!WithAI

今なら完全無料でAIを学べる!

  • 動画や実践で楽しく学べる:初心者でも安心のカリキュラム
  • スマホ・PCどちらでもOK:好きな時間に学習できる
  • 料金は一切ナシ0円でAIスキルが身につく

目的に合わせて選べる「AI副業」「AI転職」「AI活用」の3コースを用意。副収入・キャリアチェンジ・日常の生産性アップまで、あなたのゴールに合わせてAIを学べます。

会員登録はカンタン30秒で完了します。まずは公式LINEから、無料でAI学習をスタートしましょう!

この記事を書いた人

WithCodeでWeb制作を習得後、フリーランスエンジニアとして活動。HTML/CSS・JavaScript・WordPress案件を中心に年間20件以上の制作実績を持つ。「難しい技術をわかりやすく」をモットーに、初心者〜中級者向けの技術記事を執筆。副業・フリーランス独立を目指す方に向けた情報発信に注力している。

– service –WithGroupの運営サービス

  • WithCode
    - ウィズコード -

    スクール

    「未経験」から
    現場で通用する
    スキルを身に付けよう!

    詳細はこちら
  • WithFree
    - ウィズフリ -

    実案件サポート

    制作会社のサポート下で
    実務経験を積んでいこう!

    詳細はこちら

公式サイト より
今すぐ
無料カウンセリング
予約!

目次