はてなブログを見ていて足りないものに気付きました。それは見出しごとのアンカーリンクです。
割と参照するときによく使うのであってほしい機能ですが、パッと見たところ公式テーマにもそのようなものはないためDIYしましょうというやつぽいです。
まずは結論
以下のようなコードをデザイン設定のフッタ枠に貼り付けてください。
<script> document.addEventListener('DOMContentLoaded', function() { const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); const excludeIds = ['title', 'blog-description']; // ブログタイトルとブログ説明は除外する headings.forEach(function(heading) { if (heading.id && !excludeIds.includes(heading.id)) { heading.style.cursor = 'pointer'; heading.style.position = 'relative'; heading.classList.add('clickable-heading'); heading.addEventListener('click', function(e) { if (e.target.tagName === 'A') return; window.location.hash = heading.id; }); // PCでのみ表示するアイコンを追加 const anchor = document.createElement('span'); anchor.innerHTML = '#'; anchor.className = 'heading-anchor-icon'; heading.appendChild(anchor); } }); }); </script> <style> html { scroll-behavior: smooth; } .clickable-heading:hover { color: #007cba; transition: color 0.2s ease; } .heading-anchor-icon { position: absolute; left: -25px; top: 50%; transform: translateY(-50%); opacity: 0; transition: opacity 0.2s ease; color: #666; font-weight: normal; pointer-events: none; } .clickable-heading:hover .heading-anchor-icon { opacity: 0.7; } /* PC表示時のみアイコンを表示(768px以上) */ @media (min-width: 768px) { .heading-anchor-icon { display: inline; } /* 見出しの左余白を確保(PC時のみ) */ h1, h2, h3, h4, h5, h6 { margin-left: 30px; } } /* スマホ表示時はアイコンを非表示 */ @media (max-width: 767px) { .heading-anchor-icon { display: none; } /* スマホ時は左余白をリセット */ h1, h2, h3, h4, h5, h6 { margin-left: 0; } } </style>
実際にブログに適用するときは minify するなどしてから埋め込んでやると良いでしょう。
上記のコードを Terserで minify した結果を以下に示します。
<script>document.addEventListener("DOMContentLoaded",(function(){const e=document.querySelectorAll("h1, h2, h3, h4, h5, h6"),n=["title","blog-description"];e.forEach((function(e){if(e.id&&!n.includes(e.id)){e.style.cursor="pointer",e.style.position="relative",e.classList.add("clickable-heading"),e.addEventListener("click",(function(n){"A"!==n.target.tagName&&(window.location.hash=e.id)}));const n=document.createElement("span");n.innerHTML="#",n.className="heading-anchor-icon",e.appendChild(n)}}))}))</script><style>html{scroll-behavior:smooth}.clickable-heading:hover{color:#007cba;transition:color .2s ease}.heading-anchor-icon{position:absolute;left:-25px;top:50%;transform:translateY(-50%);opacity:0;transition:opacity .2s ease;color:#666;font-weight:400;pointer-events:none}.clickable-heading:hover .heading-anchor-icon{opacity:.7}@media (min-width:768px){.heading-anchor-icon{display:inline}h1,h2,h3,h4,h5,h6{margin-left:30px}}@media (max-width:767px){.heading-anchor-icon{display:none}h1,h2,h3,h4,h5,h6{margin-left:0}}</style>
やっていること
今回紹介した JavaScript のコードを以下に示します。
document.addEventListener('DOMContentLoaded', function() { const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); const excludeIds = ['title', 'blog-description']; // ブログタイトルとブログ説明は除外する headings.forEach(function(heading) { if (heading.id && !excludeIds.includes(heading.id)) { heading.style.cursor = 'pointer'; heading.style.position = 'relative'; heading.classList.add('clickable-heading'); heading.addEventListener('click', function(e) { if (e.target.tagName === 'A') return; window.location.hash = heading.id; }); // PCでのみ表示するアイコンを追加 const anchor = document.createElement('span'); anchor.innerHTML = '#'; anchor.className = 'heading-anchor-icon'; heading.appendChild(anchor); } }); });
やっていることはシンプルで、見出しに id 属性が設定されているのでクリックされたら location.hash に id をつけるという処理です。
ただ、ヘッダにリンクが設定されている場合やブログタイトル、ブログ説明については除外するような仕組みにしています。
html { scroll-behavior: smooth; } .clickable-heading:hover { color: #007cba; transition: color 0.2s ease; } .heading-anchor-icon { position: absolute; left: -25px; top: 50%; transform: translateY(-50%); opacity: 0; transition: opacity 0.2s ease; color: #666; font-weight: normal; pointer-events: none; } .clickable-heading:hover .heading-anchor-icon { opacity: 0.7; } /* PC表示時のみアイコンを表示(768px以上) */ @media (min-width: 768px) { .heading-anchor-icon { display: inline; } /* 見出しの左余白を確保(PC時のみ) */ h1, h2, h3, h4, h5, h6 { margin-left: 30px; } } /* スマホ表示時はアイコンを非表示 */ @media (max-width: 767px) { .heading-anchor-icon { display: none; } /* スマホ時は左余白をリセット */ h1, h2, h3, h4, h5, h6 { margin-left: 0; } }
CSS の方は PC 表示とスマホ表示で挙動がやや異なる用意しています。
PC の方はちょっとおしゃれに # がタイトルの左に出るようにしています。
一方でスマホ表示の場合は幅がないので # は表示させずに色が変わるだけにとどめています。
アンカーリンクお試し会場
アンカーリンクの動作をお試しする会場
Heading 3
Heading 3 の中身
Heading 4
Heading 4 の中身
https://example.com のリンク
ここの見出しは https://example.com に飛ぶよ。