「クリックしたら音を鳴らしたい」「メニューを開きたい」。そんなとき、つい <a href="#"> でリンクっぽい要素を作っていませんか。
私も昔やりました。クリックでページを開くのではなく音声を再生する仕組みを作ったとき、<a href="#" onclick="…"> と書いたんです。動きはしたものの、クリックするたびに画面がページ先頭までスクロールして戻ってしまう。原因は、まさにこの href="#" でした。
この記事では、クリックでJavaScriptを動かす要素を <a href="#"> で作るのをやめ、2026年現在のベストプラクティスである <button> 要素で正しく書き直す方法を、実例つきで解説します。
13年前にこの記事を書いたときは「javascript:void(0) を使えばOK」と紹介していました。でも今は事情が変わっています。アクセシビリティやSEOの観点から、もっとシンプルで安全なやり方が定着しました。Web制作を長年やってきた立場から見ても、ここは一度きちんと整理しておく価値があります。
「ダミーリンク」という発想そのものを卒業して、用途に合った要素を選べるようになるのがゴールです。難しい話はありません。ボタンはボタン、リンクはリンク。その線引きさえ分かれば、半分は解決したようなものです。
具体的には、href="#" のどこに問題があるのか、<button> でどう書き直すのか、見た目だけリンクにしたいときのCSSの当て方、そして既存サイトに残った古い書き方との付き合い方まで、順番に見ていきます。コピペで使えるコード例も用意したので、手を動かしながら読んでもらえればと思います。
そもそも href=”#” の何が問題なのか
<a>(アンカー要素)は本来、別のページや同じページ内の場所へ「移動する」ためのものです。そこに href="#" を入れると、ブラウザは「ページの先頭(id のないフラグメント)へ移動しろ」という指示だと解釈します。
だからクリックするとページがスクロールして上に戻ってしまう。私がハマったのはこれでした。クリックで何かのアクションをさせたいだけなのに、リンク用の要素を使ったせいで「移動」という余計な動作が付いてくるわけです。
問題はそれだけではありません。URLの末尾に # が残って履歴が汚れる、リンクをコピーしても意味のあるURLにならない、新しいタブで開いても何も起きない。検索エンジンも「どこにも繋がらないリンク」として扱うので、SEO上もプラスになりません。
MDN(Mozillaの開発者向けドキュメント)も、アンカー要素を onclick で疑似ボタンとして使うのは href に "#" や "javascript:void(0)" を入れる典型的な誤用だと明記しています。これらはコピーや別タブ表示、ブックマーク時に予期しない挙動を招き、スクリーンリーダーにも誤った意味を伝えてしまう、と。
ページ内リンクで位置がずれる話に興味があれば、こちらも参考になります。
関連記事:【jQuery】固定ヘッダによるページ内リンク位置ずれの解消方法
出典:HTML: アクセシビリティの良い基礎(MDN Web Docs)
結論:クリックで動かすなら button 要素を使う
答えはとてもシンプルです。クリックして「何かを実行する」要素は、<a> ではなく <button type="button"> で作りましょう。
覚え方は「リンクは移動、ボタンは実行」。別のページへ飛ぶなら <a>、メニューを開く・音を鳴らす・モーダルを表示するといった動作なら <button>。これがそのまま判断基準になります。
私が13年前にハマった音声再生も、いま作り直すならボタン一択です。書き方はこうなります。
<button type="button" id="playSound">音を鳴らす</button>
<script>
document.getElementById('playSound').addEventListener('click', function () {
// ここでやりたい処理を書く
new Audio('sound.mp3').play();
});
</script>
ポイントは type="button" を付けること。<button> はフォームの中に置くと既定で送信ボタン(type="submit")として扱われ、意図せずフォームが送信されてしまいます。アクション用なら type="button" を明示しておくと安心です。
そして onclick="…" をHTMLに直接書くのではなく、上のように addEventListener でJavaScript側からイベントを登録するのが今どきの書き方です。HTMLとスクリプトが分離されて見通しがよくなり、複数の処理を後から足すのも簡単になります。
<button> を使う最大の利点はアクセシビリティです。キーボードの Tab キーでフォーカスでき、Enter や Space で実行できる。スクリーンリーダーも「ボタンです」と正しく読み上げてくれます。これらは <a href="#"> や <span> では自分で作り込まないと得られない機能で、ボタンなら最初から備わっています。
クリックでクラスを付け外しする具体的なサンプルは、こちらの記事にまとめています。
関連記事:【JavaScript】ボタンクリックで別の要素にclassが追加・削除されるサンプルコード
出典:<button>: ボタン要素(MDN Web Docs)
どうしてもリンクの見た目にしたいときは
「デザイン上どうしてもリンク(テキストリンク)の見た目にしたい」という相談はよくあります。気持ちは分かりますが、見た目はCSSで作れるので、要素そのものは <button> のままにしておくのが正解です。
ボタンの装飾を消してリンク風に見せるCSSを当てれば、意味(ボタン)と見た目(リンク)を両立できます。
<button type="button" class="link-style">詳しく見る</button>
<style>
.link-style {
background: none;
border: none;
padding: 0;
color: #0066cc;
text-decoration: underline;
cursor: pointer;
font: inherit;
}
</style>
これで見た目はただのテキストリンク、中身はキーボード操作もできる正しいボタン、というおいしいとこ取りができます。cursor: pointer; を入れておくと、マウスを乗せたときに指のアイコンになってクリックできると伝わりやすくなります。
span や div で代用するのはおすすめしない
古い記事では <span style="cursor: pointer" onclick="…"> という方法も紹介していました。たしかに動きはします。ですが <span> や <div> はもともと意味を持たない要素なので、ボタンとして使うには role="button" と tabindex="0" を付け、さらに Enter / Space キーでの実行をJavaScriptで自前実装する必要があります。
<button> なら何もしなくても手に入る機能を、わざわざ作り直すことになるわけです。同じ動きが標準要素で得られるなら、自前で再現するより素直に <button> を使うほうが、バグも少なく保守もラクになります。
href=”#” や javascript:void(0) との付き合い方
とはいえ、既存サイトを引き継いだら <a href="#"> や javascript:void(0) が大量に残っていた、というのは現場あるあるです。すぐ全部は直せないときの対処も押さえておきましょう。
どうしても <a> のまま動かす必要がある場合は、クリック時にデフォルト動作を止めます。onclick="return false" でも止まりますが、今は event.preventDefault() を使うのが一般的です。
<a href="#" id="legacyLink">リンク</a>
<script>
document.getElementById('legacyLink').addEventListener('click', function (event) {
event.preventDefault(); // ページ先頭ジャンプを防ぐ
// ここで処理を書く
});
</script>
preventDefault() を呼ぶと、href="#" によるページ先頭への移動をキャンセルできます。これで「クリックすると上に戻る」問題は解消します。
一方、href="javascript:void(0)" という書き方は、今はおすすめしません。MDNはアクセシビリティとセキュリティの両面から javascript: から始まるURL自体を避けるべきだとしています。サイトによってはコンテンツセキュリティポリシー(CSP)でブロックされて動かないこともあります。
整理すると、優先順位はこうです。まず可能なら <button> に置き換える。それが無理ならアンカーのまま preventDefault() で止める。javascript:void(0) は新規では使わない。この順番で考えておけば、まず外しません。
出典:Event.preventDefault()(MDN Web Docs)
まとめ:ダミーリンクという発想から卒業しよう
13年前の自分に一番伝えたいのは、「クリックで動かしたいならリンクじゃなくてボタンを使え」という一言です。
あらためて要点を振り返ります。<a href="#"> はページ先頭へのジャンプ、履歴の汚れ、コピー時の不具合、SEOやアクセシビリティ上のマイナスを抱えています。クリックで何かを実行する要素は <button type="button"> で作るのが2026年の正解です。
リンクの見た目にしたいだけなら、要素はボタンのままCSSで装飾を変えればOK。<span> や <div> での代用は、わざわざ手間を増やすことになるので避けましょう。既存の href="#" をすぐ直せないときは preventDefault() でしのぎ、javascript:void(0) は新しく書かない。
「ダミーリンク」を作るという発想そのものを手放して、リンクは移動・ボタンは実行と役割で選ぶ。これだけで、コードはぐっと正しく、使う人にもやさしくなります。
Web制作の正解は、時代とともに少しずつ動いていきます。javascript:void(0) が当たり前だった頃と違い、今はブラウザもJavaScriptもアクセシビリティの考え方も成熟しました。だからこそ、過去に書いたコードをそのまま信じ続けるのではなく、たまに今のやり方へアップデートしてあげるのが大切だと感じています。
今お使いのサイトに href="#" が潜んでいないか、この機会に一度見直してみてください。直し方はもう分かっているはずです。WeberNoteでは、こうした「昔は正解だったけど今は変わった」Web制作の小ネタをこれからも更新していきます。