<html data-theme="light">
<body>
<main class="p-mode-change">
<p class="p-mode-change__above">Now, you are using<strong class="p-mode-change__lead">Light Mode</strong></p>
<div class="p-mode-change__below">
<p class="p-mode-change__text">If your eyes are tired, <br />you should use <span class="">dark mode.</span></p>
<button id="toggleButton" type="button" class="p-mode-change__toggle"></button>
</div>
</main>
</body>
</html>
:root {
// ブラウザへテーマ認識を伝える
color-scheme: light dark;
// light-dark()は、引数に応じて、lightモードとdarkモードで異なる値を返す
--bg-color: light-dark(#fff, #111);
--txt-color: light-dark(#111, #fff);
--line-color: light-dark(#333, #ccc);
--gray-main: light-dark(#666, #999);
// モード切り替えの対象外の色についてはユニークな変数名を命名
--unique-white: #fff;
--unique-gray: #ddd;
--unique-green: #4ade80;
}
[data-theme="light"] {
--bg-color: #fff;
--txt-color: #111;
--line-color: #333;
--gray-main: #666;
}
[data-theme="dark"] {
// darkモードの時に上書きする変数
--bg-color: #111;
--txt-color: #fff;
--line-color: #ccc;
--gray-main: #999;
}
body {
font-family: Arial, Helvetica, sans-serif;
margin: 0;
padding: 0;
line-height: normal;
background-color: var(--bg-color);
}
.p-mode-change {
height: 100vh;
min-height: 700px;
max-width: calc(100vw - 40px);
padding-inline: 20px;
margin-inline: auto;
padding-top: 50px;
&__above {
color: var(--txt-color);
font-size: 30px;
}
&__lead {
display: block;
font-size: 150px;
font-weight: bold;
}
&__below {
border-top: var(--line-color) 1px solid;
margin-top: 45px;
padding-top: 45px;
color: var(--gray-main);
font-size: 50px;
font-weight: bold;
span {
color: var(--txt-color);
}
}
&__toggle {
border: transparent 1px solid;
position: relative;
display: block;
margin-top: 30px;
width: 56px;
height: 28px;
border-radius: 14px;
background-color: var(--unique-gray);
cursor: pointer;
&::after {
content: "";
position: absolute;
top: 50%;
left: 2px;
width: 20px;
height: 20px;
border-radius: 14px;
transform: translateY(-50%);
background-color: var(--unique-white);
transition: left 0.2s;
}
&--is-on {
background-color: var(--unique-green);
&::after {
left: calc(100% - 22px);
}
}
}
}
View Compiled
const toggleButton = document.getElementById("toggleButton");
const mainText = document.querySelector(".p-mode-change__lead");
const subText = document.querySelector(".p-mode-change__text");
// テーマの状態管理
const themeStore = {
DARK: "dark",
LIGHT: "light",
get theme() {
const theme = localStorage.getItem("theme");
return theme === this.DARK ? this.DARK : this.LIGHT;
},
set theme(value) {
localStorage.setItem("theme", value);
document.documentElement.setAttribute("data-theme", value);
}
};
// テーマの更新
function updateTheme(theme) {
themeStore.theme = theme;
const isDark = theme === themeStore.DARK;
toggleButton.classList.toggle("p-mode-change__toggle--is-on", isDark);
toggleButton.setAttribute("aria-pressed", isDark);
if (isDark) {
mainText.innerHTML = "Dark Mode";
subText.innerHTML =
"If you prefer brighter contents, <br>you should use <span>light mode.</span>";
} else {
mainText.innerHTML = "Light Mode";
subText.innerHTML =
"If your eyes are tired, <br>you should use <span>dark mode.</span>";
}
}
// 初期テーマの適用
updateTheme(themeStore.theme);
// トグルボタンのクリックイベント
toggleButton.addEventListener("click", function () {
const currentTheme = themeStore.theme;
const newTheme =
currentTheme === themeStore.DARK ? themeStore.LIGHT : themeStore.DARK;
updateTheme(newTheme);
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.