パーツ番号 06-09-10 ・ JavaScript使用
フローティング追従ミニ目次カプセル
現在の見出し名を表示するピル型カプセルが下部に固定追従し、タップでミニ目次を展開します。WordPressのモバイル記事に最適な省スペース目次。スクロールで動作します。
プレビュー
ソースコード
HTML
<div class="d06-09-10-wrap">
<div class="d06-09-10-body">
<section id="s06-09-10-1"><h4>はじめに</h4><p>下部のカプセルが現在の見出しを表示しながら追従します。</p></section>
<section id="s06-09-10-2"><h4>背景</h4><p>フローティング目次は本文の邪魔をせず、必要な時だけ開いて使えます。</p></section>
<section id="s06-09-10-3"><h4>手順</h4><p>カプセルをタップするとミニリストが上に開き、見出しへ直接移動できます。</p></section>
<section id="s06-09-10-4"><h4>注意点</h4><p>本文と重ならないよう、下部に余白を確保して配置します。</p></section>
<section id="s06-09-10-5"><h4>まとめ</h4><p>省スペースかつ現在地が分かる、モバイルとも相性の良い目次形式です。</p></section>
</div>
<div class="d06-09-10-capsule">
<div class="d06-09-10-list">
<a data-t="s06-09-10-1">はじめに</a>
<a data-t="s06-09-10-2">背景</a>
<a data-t="s06-09-10-3">手順</a>
<a data-t="s06-09-10-4">注意点</a>
<a data-t="s06-09-10-5">まとめ</a>
</div>
<button class="d06-09-10-cur" type="button">
<span class="d06-09-10-dot"></span>
<span class="d06-09-10-txt">はじめに</span>
<span class="d06-09-10-arrow">▾</span>
</button>
</div>
</div>CSS
.prev.d06-09-10{padding:0;display:block}
.d06-09-10-wrap{position:relative;height:260px}
.d06-09-10-body{height:100%;overflow-y:auto;box-sizing:border-box;padding:16px 16px 54px;scroll-behavior:smooth}
.d06-09-10-body section{padding:6px 0 16px;border-bottom:1px dashed #eef0f5}
.d06-09-10-body h4{margin:0 0 6px;font-size:13px;color:#242a3d}
.d06-09-10-body p{margin:0;font-size:12px;color:#666c80;line-height:1.7}
.d06-09-10-capsule{position:absolute;left:50%;bottom:12px;transform:translateX(-50%);z-index:2;display:flex;flex-direction:column;align-items:center}
.d06-09-10-cur{display:flex;align-items:center;gap:7px;font-size:11px;font-weight:700;color:#3a2f6b;background:#fff;
border:1px solid #e6e8f0;border-radius:20px;padding:8px 16px;cursor:pointer;box-shadow:0 6px 16px rgba(40,50,90,.14)}
.d06-09-10-dot{width:7px;height:7px;border-radius:50%;background:#5b3df0;flex:none}
.d06-09-10-arrow{transition:transform .25s;font-size:9px}
.d06-09-10-capsule.is-open .d06-09-10-arrow{transform:rotate(180deg)}
.d06-09-10-list{order:-1;margin-bottom:8px;background:#fff;border:1px solid #e6e8f0;border-radius:12px;padding:6px;
display:flex;flex-direction:column;gap:2px;box-shadow:0 10px 22px rgba(40,50,90,.16);
max-height:0;overflow:hidden;opacity:0;transition:max-height .3s,opacity .25s;width:150px}
.d06-09-10-capsule.is-open .d06-09-10-list{max-height:200px;opacity:1}
.d06-09-10-list a{padding:7px 10px;border-radius:6px;font-size:11px;color:#4a5068;text-decoration:none;text-align:center}
.d06-09-10-list a:hover,.d06-09-10-list a.is-active{background:#eceaff;color:#3a49d6}JavaScript
(function(){
var root=document.getElementById('item-06-09-10');if(!root)return;
var body=root.querySelector('.d06-09-10-body');
var capsule=root.querySelector('.d06-09-10-capsule');
var curBtn=root.querySelector('.d06-09-10-cur');
var txt=root.querySelector('.d06-09-10-txt');
var links=root.querySelectorAll('.d06-09-10-list a');
var secs=root.querySelectorAll('.d06-09-10-body section');
function upd(){
var st=body.scrollTop+30,cur=secs[0];
secs.forEach(function(s){if(s.offsetTop-body.offsetTop<=st)cur=s;});
var title=cur.querySelector('h4').textContent;
txt.textContent=title;
links.forEach(function(a){a.classList.toggle('is-active',a.getAttribute('data-t')===cur.id);});
}
curBtn.addEventListener('click',function(){capsule.classList.toggle('is-open');});
links.forEach(function(a){
a.addEventListener('click',function(e){
e.preventDefault();
var t=root.querySelector('#'+a.getAttribute('data-t'));
if(t){body.scrollTop=t.offsetTop-body.offsetTop-6;}
capsule.classList.remove('is-open');
});
});
body.addEventListener('scroll',upd);upd();
})();クラス名 .d06-09-10 は本ライブラリ内での識別用です。複数のパーツを同じページで使う場合は、重複しないよう名前を変更してください。