<!-- .slide を増やすとドットも自動で増えます(実画像なら中身を img に) --> <div class="bnto-sldr" data-bnto-slider> <div class="view"> <div class="track"> <div class="slide s1">1</div> <div class="slide s2">2</div> <div class="slide s3">3</div> </div> </div> <button type="button" class="nav prev" aria-label="前のスライドへ">‹</button> <button type="button" class="nav next" aria-label="次のスライドへ">›</button> <div class="dots"></div> </div>
.bnto-sldr { --c1: hsl(160 52% 40%); /* 矢印・ドットの色 */ position: relative; max-width: 290px; /* 幅はお好みで */ } .bnto-sldr .view { overflow: hidden; border-radius: 14px; } /* スライドを横一列に並べ、track ごと transform で動かす */ .bnto-sldr .track { display: flex; transition: transform .45s cubic-bezier(.25, .8, .3, 1); } .bnto-sldr .slide { flex: 0 0 100%; height: 150px; display: grid; place-items: center; font-size: 36px; font-weight: 900; color: #fff; } /* デモ用スライド(実画像に差し替えOK) */ .bnto-sldr .s1 { background: linear-gradient(135deg, #2BB3A3, #3D6FB0); } .bnto-sldr .s2 { background: linear-gradient(135deg, #8E6FD8, #D8598C); } .bnto-sldr .s3 { background: linear-gradient(135deg, #E8874C, #D84C5B); } .bnto-sldr .nav { position: absolute; top: 59px; width: 32px; height: 32px; border-radius: 50%; border: 0; background: rgba(255,255,255,.92); color: var(--c1); font-size: 18px; font-weight: 900; line-height: 1; cursor: pointer; display: grid; place-items: center; box-shadow: 0 2px 8px rgba(29,42,54,.25); } .bnto-sldr .prev { left: 8px; } .bnto-sldr .next { right: 8px; } .bnto-sldr .dots { display: flex; gap: 7px; justify-content: center; margin-top: 10px; } .bnto-sldr .dot { width: 9px; height: 9px; border-radius: 50%; border: 0; padding: 0; background: #C6D4DF; cursor: pointer; } .bnto-sldr .dot.is-on { background: var(--c1); }
// 前後ボタンとドットでスライドを切り替える基本形(複数設置OK) (function () { document.querySelectorAll('[data-bnto-slider]').forEach(function (box) { if (box.dataset.bntoInit) return; box.dataset.bntoInit = '1'; var track = box.querySelector('.track'); var total = track.children.length; var dotsBox = box.querySelector('.dots'); var cur = 0, dots = []; for (var i = 0; i < total; i++) { var d = document.createElement('button'); d.type = 'button'; d.className = 'dot'; d.setAttribute('aria-label', (i + 1) + '枚目を表示'); (function (n) { d.addEventListener('click', function () { go(n); }); })(i); dotsBox.appendChild(d); dots.push(d); } function go(n) { cur = (n + total) % total; // 端では反対側へ回り込む track.style.transform = 'translateX(-' + cur * 100 + '%)'; dots.forEach(function (d, i) { d.classList.toggle('is-on', i === cur); }); } box.querySelector('.prev').addEventListener('click', function () { go(cur - 1); }); box.querySelector('.next').addEventListener('click', function () { go(cur + 1); }); go(0); }); })();
使い方のコツ
スライドを増やすときは .slide のdivを足すだけで、ドットは枚数に合わせて自動生成されます。実際の画像を使う場合は、スライドの中に <img> を入れて width: 100%; height: 100%; object-fit: cover; を指定してください。切替の速さは .track の transition で調整できます。