「この用語、なんだっけ?」と思った読者にサッと補足を出したい。ボタンの横に小さな注釈を添えたい。そんなとき、わざわざJavaScriptを書くのは正直おっくうですよね。
マウスを乗せた瞬間にメッセージがふわっと出てくる、いわゆるポップアップやツールチップ。商品名の横に小さな説明を添えたり、専門用語にそっと注釈を付けたり。サイトをちょっと親切にしてくれる、あの仕掛けです。実はあれ、jQueryなどのスクリプトを一切使わず、HTMLとCSSだけで十分に実装できます。仕組みさえ分かってしまえば、コードをコピペして数行いじるだけで、自分のサイトにそのまま組み込めます。
私はWeb制作を25年やってきましたが、この「CSSだけツールチップ」は今でも現場で重宝する定番テクニックです。なにしろ軽い。JavaScriptを読み込まない分だけページ表示も速いし、スクリプトのエラーで動かなくなる、といった事故もありません。手数が少なくて壊れにくいので、ちょっとした補足表示なら真っ先にこれを選びます。
とはいえ、ただコピペするだけだと「スマホで動かない」「キーボードだと使えない」といった落とし穴にハマりがちなのも事実です。そこでこの記事では、基本の:hover表示から、ふわっと出すアニメーション、吹き出しの三角作り、data-属性を使ったスマートな書き方、そしてスマホやキーボード操作への配慮、さらに新しいpopover属性まで、2026年の今おさえておきたい形で順番にまとめます。コピペで使えるサンプルコードも各所に用意したので、気になるところから試してみてください。
CSSだけでポップアップを表示する基本の仕組み
まずは土台となる考え方から。ポップアップ表示の正体は、ものすごくシンプルです。
「普段は隠しておいた要素を、マウスが乗ったときだけ表示に切り替える」。たったこれだけです。
隠すにはdisplay: none、出すにはdisplay: block。そして「マウスが乗ったとき」を表すのが、CSSの:hoverという擬似クラスです。MDNでも:hoverは「ユーザーがポインティングデバイスで要素に反応したときに一致する」もので、「マウスポインターを要素の上に動かしたとき」に発動すると説明されています。
最小構成のサンプルコード
下が一番シンプルな例です。テキストにマウスを乗せると、隠れていたメッセージが出てきます。
<span class="tip">
WeberNoteってブログ、知ってる?
<span class="tip-text">Web制作の小ネタを書いてるブログです</span>
</span>
.tip {
position: relative; /* 吹き出しの基準位置にする */
border-bottom: 1px dotted #666;
cursor: help;
}
.tip .tip-text {
display: none; /* 普段は隠す */
position: absolute;
top: 1.6em;
left: 0;
width: 14em;
padding: 0.5em 0.8em;
background: #333;
color: #fff;
border-radius: 4px;
font-size: 0.85em;
line-height: 1.4;
}
.tip:hover .tip-text {
display: block; /* マウスが乗ったら出す */
}
ポイントは親要素にposition: relative;、ポップアップ側にposition: absolute;を指定することです。これで吹き出しが親要素を基準にして好きな位置へ浮かびます。topやleftの値を変えれば、上・下・横と自由に配置できます。
絶対配置(position: absolute)を使う理由は、ポップアップを「文章の流れから浮かせる」ためです。これをしないと、メッセージが表示された瞬間に下の文章が押し下げられて、レイアウトがガタッと動いてしまいます。基準になる親にrelativeを置いておくのが、崩れない配置のコツです。
opacityとvisibilityでふわっと表示するアニメーション
基本形のdisplay: none → blockは確実に動きますが、ひとつだけ弱点があります。displayプロパティはCSSのトランジション(アニメーション)で滑らかに変化させられないのです。MDNでもdisplayのアニメーション可否について、滑らかな補間の対象外として扱われています。そのため、パッと一瞬で出てしまい、少し素っ気ない印象になります。
そこで現場でよく使うのが、opacity(透明度)とvisibilityを組み合わせる方法です。これなら、じわっと浮かび上がる上品な動きが作れます。
なぜopacityだけではダメなのか
「opacity: 0で透明にすればいいのでは?」と思うかもしれません。ところがopacity: 0は見た目が透明になるだけで、要素はその場に存在し続けます。MDNの解説でも、opacity: 0の要素は透明でも「スペースを占有する」とされています。つまり透明な吹き出しが見えない壁のように残り、マウス操作の邪魔をすることがあります。
かといってdisplay: noneに戻すとアニメーションができない。このジレンマを解くのがvisibilityです。visibility: hiddenはMDNによると、要素を不可視にしつつ「通常どおりレイアウトに影響する」性質を持ちますが、重要なのはvisibilityはトランジションで変化させられる(離散的なステップとして補間される)点です。opacityで透明度をなめらかに、visibilityで表示・非表示を切り替える。この二段構えが定番です。
ふわっと出すサンプルコード
.tip .tip-text {
position: absolute;
top: 1.6em;
left: 0;
width: 14em;
padding: 0.5em 0.8em;
background: #333;
color: #fff;
border-radius: 4px;
/* 初期状態:透明&非表示 */
opacity: 0;
visibility: hidden;
/* 0.2秒かけて変化させる */
transition: opacity 0.2s ease, visibility 0.2s ease;
}
.tip:hover .tip-text {
opacity: 1;
visibility: visible; /* マウスで表示&ふわっと */
}
これでマウスを乗せると約0.2秒かけてふわっと現れ、外すとすっと消えます。transitionの秒数を0.3sなどに伸ばせばゆったり、0.1sにすればキビキビ。サイトの雰囲気に合わせて微調整してください。transform: translateY(4px)を初期値に足して、表示時にtranslateY(0)へ戻すと、少し下からせり上がる動きも作れます。
出典:visibility – CSS(MDN Web Docs)
疑似要素で吹き出しの三角(しっぽ)を作る
ツールチップらしさをグッと上げてくれるのが、吹き出しの「しっぽ」、つまり三角形のとんがりです。これも画像は不要で、::beforeや::afterという疑似要素とCSSのボーダーだけで描けます。
三角形は、幅と高さを0にした要素に太いボーダーを付け、不要な辺を透明にすると作れます。これはCSSでアイコンや矢印を描くときの王道テクニックです。
三角形を足すサンプルコード
.tip .tip-text::after {
content: ""; /* 疑似要素には必須 */
position: absolute;
bottom: 100%; /* 吹き出しの上辺に配置 */
left: 1.5em;
border: 6px solid transparent;
border-bottom-color: #333; /* 上向きの三角になる */
}
仕組みは、borderを全方向transparent(透明)にしておき、三角を出したい向きと逆側の辺だけ色を付ける、というものです。上の例では下辺だけ背景色と同じ#333にしているので、上向きの三角ができ、吹き出しの本体と一体化して見えます。吹き出しを下に出すならborder-top-colorを、左右ならborder-right-colorやborder-left-colorを使います。
content: ""を忘れると疑似要素そのものが生成されないので、空でも必ず書いておきましょう。
data属性で書く、もっとスマートなツールチップ
「メッセージのたびに<span>を追加するのは面倒」という場合、HTMLのdata-属性にテキストを書いておき、CSSのcontent: attr()で読み出す方法がおすすめです。マークアップがスッキリして、保守もしやすくなります。
MDNによればattr()関数は「選択された要素、または疑似要素の生成元要素の属性値を取得する」もので、contentプロパティと組み合わせて生成内容として差し込めます。これを使うと、テキストをHTML側に持たせたまま、見た目はCSSだけで完結します。
data属性ツールチップのサンプルコード
<span class="tooltip" data-tip="ここに補足が出ます">用語</span>
.tooltip {
position: relative;
border-bottom: 1px dotted #666;
cursor: help;
}
.tooltip::after {
content: attr(data-tip); /* data-tipの値を表示 */
position: absolute;
top: 1.6em;
left: 0;
white-space: nowrap;
padding: 0.4em 0.7em;
background: #333;
color: #fff;
border-radius: 4px;
font-size: 0.85em;
opacity: 0;
visibility: hidden;
transition: opacity 0.2s ease, visibility 0.2s ease;
}
.tooltip:hover::after,
.tooltip:focus::after {
opacity: 1;
visibility: visible;
}
この書き方なら、ツールチップを増やしたいときはdata-tip="..."を足すだけ。CSSは一度書けば使い回せます。注釈をたくさん散りばめる用語集やヘルプ表示にぴったりです。なおattr()は、指定した属性が存在しないと空文字を返す仕様なので、表示したい要素には必ずdata-tipを付けておきましょう。
出典:content – CSS(MDN Web Docs)
スマホとキーボード操作への配慮(アクセシビリティ)
ここが、コピペ記事ではよく抜け落ちるけれど一番大事なところです。:hoverには「マウスがない環境では発動しない・しても不安定」という弱点があります。
MDNも:hoverについて「タッチスクリーンでは問題がある」と明言しています。ブラウザによって「まったく一致しない」「タッチした直後の一瞬だけ一致する」「別の要素を触るまで一致し続ける」など挙動がバラバラなのです。つまりスマホやタブレットでは、ホバー前提のツールチップは正しく動かないことを覚悟しておく必要があります。MDNは「ホバー機能が限定的、または存在しないデバイスでもコンテンツにアクセスできるようにすべき」と推奨しています。
:focusも一緒に指定する
対策の第一歩は、:hoverと一緒に:focusを指定することです。先ほどのdata属性の例でも.tooltip:focus::afterを併記しました。こうすると、キーボードのTabキーで要素にフォーカスしたときにもツールチップが出ます。マウスを使えない人にも届くようになります。
ただし<span>のような要素は標準ではフォーカスを受け取れません。キーボードでも開きたいならtabindex="0"を付けるか、ボタンやリンクなど最初からフォーカス可能な要素を土台に使ってください。
本当に重要な情報はホバーに頼らない
結論として、ホバー式ツールチップは「あれば嬉しい補足」までに留め、絶対に伝えたい情報はホバーに依存させないのが鉄則です。価格や注意書きのような必須情報は、最初から本文に書くか、常時表示しておく。これがデバイスを選ばない一番確実な設計です。装飾的なツールチップと、必読の情報。この線引きを意識するだけで、ぐっと親切なサイトになります。
関連記事:【CSS】横並びメニューの区切り線を隣接セレクタと疑似要素で実装する方法
2026年の今ならこんな選択肢も(popover属性・details)
最後に、ここ数年で増えた「もっとちゃんとしたポップアップ」の選択肢にも触れておきます。CSSだけのツールチップで物足りない場面では、こちらが候補になります。
HTMLのpopover属性
注目株が、HTMLのpopover属性です。MDNによると、要素にpopover属性を付けるとポップオーバー要素として扱われ、ボタン側のpopovertarget属性やJavaScriptの呼び出しで開くまではdisplay: noneで隠れています。開いたポップオーバーは最前面(トップレイヤー)に表示され、親要素のpositionやoverflowの影響を受けないのが大きな利点です。
<button popovertarget="info">詳しく</button>
<div popover id="info">ここに説明が出ます</div>
既定のpopover="auto"なら、外側のクリックやEscキーで自然に閉じる「ライトディスミス」が効きます。MDNではこのpopover属性を「Baseline 2024(2024年4月から最新ブラウザで利用可能)」と位置づけています。つまり比較的新しい機能なので、古い環境を相手にする場合は注意が必要ですが、クリックで開閉する本格的なポップアップを軽く作りたいなら有力な選択肢です。
出典:popover – HTML(MDN Web Docs)
クリックで開閉するならdetails/summary
「ホバーじゃなくクリックで開け閉めしたい」「スマホでも確実に動かしたい」なら、<details>と<summary>も便利です。MDNによれば<details>は「開いた状態に切り替えたときだけ情報が見える開閉ウィジェットを作る」要素で、JavaScriptなしで開閉が動作します。<summary>がクリックできるラベルになり、open属性が付いている間だけ中身が見えます。
<details>
<summary>補足を見る</summary>
<p>ここに詳しい説明が入ります。</p>
</details>
こちらはタッチ操作でも確実に開閉できるので、スマホ向けのFAQや注釈に向いています。ホバー式CSSツールチップとは用途が分かれるので、覚えておくと引き出しが増えます。
出典:details – HTML(MDN Web Docs)
まとめ
CSSだけでホバー時にポップアップやツールチップ、吹き出しを表示する方法を、基本から最新の選択肢まで一気に見てきました。
おさらいすると、土台は「普段は隠して、:hoverのときだけ出す」というシンプルな発想です。display: none → blockで確実に切り替え、ふわっと見せたいならopacityとvisibilityをtransitionで動かす。位置決めは親にposition: relative、ポップアップ側にabsolute。吹き出しの三角は::afterとボーダーで描き、テキストはdata-属性+content: attr()で持たせるとマークアップがスッキリします。
そして何より忘れてはいけないのが、:hoverはスマホやタッチ操作、キーボード操作に弱いということです。マウスがない環境では発動しなかったり、挙動が不安定になったりします。だからこそ:focusも一緒に指定し、本当に大事な情報はホバーに頼らない。この一手間こそが、誰にとっても使いやすいサイトを作る分かれ目になります。装飾的な補足はツールチップで、必読の情報は本文で。この線引きを意識するだけで仕上がりがぐっと変わります。
クリックで開閉したい、スマホでも確実に動かしたい、もっと本格的に作りたい。そんなときは、新しいpopover属性や昔ながらの<details>要素も思い出してください。CSSだけのツールチップ、popover、detailsと、引き出しが増えるほど「この場面ならこれ」と最適な道具をサッと選べるようになります。技術は道具の数より、使い分けのセンスです。
難しく見えるかもしれませんが、やっていることは「隠す・出す・位置を決める」の組み合わせだけ。まずは今回の基本のサンプルコードをコピペして、自分のサイトで一度動かしてみてください。一度自分の手で動かせば、あとは自由自在にアレンジできるようになりますよ!