切り替え結果はここに反映。選択はlocalStorageに保存され、次回も維持されます。
<div class="bnto-dark" data-bnto-dark> <button type="button" class="tgl" aria-pressed="false"> <span class="knob" aria-hidden="true"></span>ダークモード </button> <!-- .view = 色が切り替わる領域(実サイトでは body 全体などに) --> <div class="view"> <b>ミニプレビュー</b> <p>切り替え結果はここに反映されます。</p> </div> </div>
.bnto-dark { --c1: hsl(256 47% 54%); /* アクセント色 */ display: flex; flex-direction: column; gap: 10px; } .bnto-dark .tgl { display: inline-flex; align-items: center; gap: 9px; align-self: flex-start; padding: 6px 14px 6px 8px; background: #fff; border: 2px solid #DFE9F1; border-radius: 999px; font: inherit; font-weight: 800; cursor: pointer; } /* トグルのつまみ */ .bnto-dark .knob { position: relative; width: 34px; height: 20px; border-radius: 999px; background: #D8D0C0; transition: background .25s; } .bnto-dark .knob::after { content: ""; position: absolute; left: 2px; top: 2px; width: 16px; height: 16px; border-radius: 50%; background: #fff; transition: transform .25s; } .bnto-dark.is-dark .knob { background: var(--c1); } .bnto-dark.is-dark .knob::after { transform: translateX(14px); } /* 切り替わる側:is-dark で色を上書き */ .bnto-dark .view { background: #fff; color: #1D2A36; border: 2px solid #DFE9F1; border-radius: 14px; padding: 14px 16px; transition: background .3s, color .3s, border-color .3s; } .bnto-dark.is-dark .view { background: #252132; color: #F2EEE6; border-color: #3C3650; }
// トグル+localStorage保存+OS設定(prefers-color-scheme)を初期値に (function () { var KEY = 'bnto-demo-theme'; // サイト本体のキーと衝突しない名前に document.querySelectorAll('[data-bnto-dark]').forEach(function (box) { if (box.dataset.bntoInit) return; box.dataset.bntoInit = '1'; var btn = box.querySelector('.tgl'); var saved = null; try { saved = localStorage.getItem(KEY); } catch (e) {} var dark = saved ? saved === 'dark' : window.matchMedia('(prefers-color-scheme: dark)').matches; apply(); btn.addEventListener('click', function () { dark = !dark; apply(); try { localStorage.setItem(KEY, dark ? 'dark' : 'light'); } catch (e) {} }); function apply() { box.classList.toggle('is-dark', dark); btn.setAttribute('aria-pressed', dark); } }); })();
使い方のコツ
サイト全体に適用するには、.view ではなく document.documentElement に is-dark を付け、配色をCSS変数(--bg / --tx など)で組んでおくのが定石です。保存キー KEY は my-site-theme のようにサイト固有の名前へ変更してください。