※ 2026/3/23 更新: 当初公開したページは確認していたつもりだったが、上手く保存されていなかったらしく、過去の記事と混ざった状態で謎のページが出来上がっていた。バックアップはとっていなかったためオリジナルの内容はわからなくなってしまったが、ひとまず内容を修正。
週末にAntigravityを入れて、Blogデザイン改善やUnityでのゲーム作成が以前と比べてはかどり始めた。今日も短時間で実行できそうなBlogデザイン改善を実行。
このBlogger記事の目次は、だいぶ前に他のサイトを参考にして自動でTOCが表示されるようにしてみた(以前の記事)が、これを改善してみることに。
Blog目次の改善
Antigravity(何も気にせず昨日使った続きでClaude Sonnet 4.6になっていた)に「Blogの目次について、現在も目次はあるが記事の上の方で固定。見た目・操作性などが良い目次にするにはどうしたら良い?」と聞いたところフローティング目次を推奨される。
1度目の結果はあまりかっこよくなかったため、もう一度Blogのデザインに合わせて考え直すように指示したら、今度はブラウザでページを参照しつつ2-3の記事も開いてまじまじと観察してから作成してくれた。
見出しレベルによって文字スタイルを変えられるようにするなどファインチューンをもう一度だけ行って完了。今回はコピペだけで内容確認せずのバイブコーディング。
フローティング目次
<style> .widget.TableOfContents, .post-body .toc, #toc, .table-of-contents { background: #f4f4f4; border-left: 4px solid #555; border-radius: 0 8px 8px 0; padding: 14px 20px; margin: 1.5em 0 2em; font-size: 0.9em; position: relative; } #ftoc-toggle { position: fixed; left: 16px; top: 50%; transform: translateY(-50%); background: #555; color: #fff; border: none; border-radius: 6px 0 0 6px; padding: 10px 7px; font-size: 0.7em; writing-mode: vertical-rl; cursor: pointer; z-index: 10000; box-shadow: -2px 0 8px rgba(0,0,0,0.15); } #floating-toc { position: fixed; left: 52px; top: 50%; transform: translateY(-50%); width: 200px; max-height: 55vh; overflow-y: auto; background: #fff; border-left: 3px solid #555; border-radius: 0 8px 8px 0; padding: 12px 14px; box-shadow: 4px 4px 16px rgba(0,0,0,0.12); font-size: 0.8em; z-index: 9999; } #floating-toc.hidden { opacity: 0; pointer-events: none; } #floating-toc a.active { color: #222; font-weight: bold; background: #eee; border-left: 3px solid #555; } @media (max-width: 900px) { #floating-toc, #ftoc-toggle { display: none; } } </style> <script> //<![CDATA[ window.addEventListener('DOMContentLoaded', function() { var post = document.querySelector('.post-body'); if (!post) return; var headings = post.querySelectorAll('h2, h3'); if (headings.length < 2) return; var btn = document.createElement('button'); btn.id = 'ftoc-toggle'; btn.textContent = '▼ 目次'; document.body.appendChild(btn); var toc = document.createElement('div'); toc.id = 'floating-toc'; var titleEl = document.createElement('div'); titleEl.style.fontWeight='bold'; titleEl.style.borderBottom='1px solid #ddd'; titleEl.style.paddingBottom='5px'; titleEl.style.marginBottom='8px'; titleEl.textContent = 'Table of Contents'; toc.appendChild(titleEl); var ul = document.createElement('ul'); ul.style.listStyle='none'; ul.style.padding='0'; var topLi = document.createElement('li'); var topA = document.createElement('a'); topA.href = 'javascript:void(0)'; topA.onclick = function(){ window.scrollTo({top: 0, behavior: 'smooth'}); }; topA.textContent = '🔝 Back to Top'; topA.style.textDecoration='none'; topA.style.color='#555'; topA.style.display='block'; topA.style.padding='3px 0'; topA.style.fontWeight = 'bold'; topA.style.borderBottom = '1px dashed #ddd'; topA.style.marginBottom = '5px'; topA.style.cursor = 'pointer'; topLi.appendChild(topA); ul.appendChild(topLi); var links = []; headings.forEach(function(h, i) { if (!h.id) h.id = 'toc-h-' + i; var li = document.createElement('li'); var a = document.createElement('a'); a.href = '#' + h.id; a.textContent = h.textContent; a.style.textDecoration='none'; a.style.color='#666'; a.style.display='block'; a.style.padding='1px 0'; if (h.tagName === 'H2') { a.style.fontWeight = 'bold'; a.style.fontSize = '1em'; } if (h.tagName === 'H3') { a.style.paddingLeft = '14px'; a.style.fontSize = '0.88em'; } li.appendChild(a); ul.appendChild(li); links.push({ el: h, link: a }); }); toc.appendChild(ul); toc.classList.add('hidden'); document.body.appendChild(toc); var open = false; btn.addEventListener('click', function() { open = !open; toc.classList.toggle('hidden', !open); btn.textContent = open ? '✕ 閉じる' : '▼ 目次'; }); window.addEventListener('scroll', function() { var scrollY = window.scrollY + 130; var current = links[0].link; links.forEach(function(item) { if (item.el.getBoundingClientRect().top + window.scrollY <= scrollY) current = item.link; }); links.forEach(function(item) { item.link.classList.remove('active'); }); current.classList.add('active'); }); }); //]]> </script>
