インターフェース上でテーマ効果を実現する方法、主に Web ページの昼と夜の配色を切り替える方法
いくつかの方法で録音しました
CSS変数
使用できますが、私の経験ではあまり良くありません。値は labelstyle
属性に表示されます。
body {
--size: 100px;
--time: 500ms;
--color1: #fff;
--color2: #000;
margin: 0;
width: 100vw;
height: 100vh;
background: var(--color1);
transition: background var(--time);
}
div {
width: var(--size);
height: var(--size);
color: var(--color1);
background: var(--color2);
transition: background var(--time);
}
<div>
文本
</div>
<script>
const div = document.querySelector("div")
const style = document.body.style
div.onclick = (() => {
let isDark = false
return () => {
if (isDark) {
style.setProperty("--color1", "#fff");
style.setProperty("--color2", "#000");
} else {
style.setProperty("--color1", "#000");
style.setProperty("--color2", "#fff");
}
isDark = !isDark
}
})()
</script>
ダイナミックなライティング
@keyframes
この段落を書いているとき、 JavaScript を使用して動的に変更する方法を探していましたが、解決策を見つけました。
タグを取得してコンテンツを直接変更する
<style id="root">
:root {
--size: 300px;
--color1: #000;
--color2: #990;
--color3: #090;
--color4: #099;
}
</style>
<style>
div {
width: var(--size);
height: var(--size);
background: var(--color1);
animation: play 5s infinite;
}
@keyframes play {
0% {
background: var(--color1);
transform: translate(0, 0);
}
25% {
background: var(--color2);
transform: translate(var(--size), 0);
}
50% {
background: var(--color3);
transform: translate(var(--size), var(--size));
}
75% {
background: var(--color4);
transform: translate(0, var(--size));
}
100% {
background: var(--color1);
transform: translate(0, 0);
}
}
</style>
<input type="number">
<button>
修改 size
</button>
<div></div>
<script>
const btn = document.querySelector("button")
const input = document.querySelector("input")
const style = document.querySelector("#root")
btn.onclick = () => {
style.innerText = `
:root {
--size: ${
input.value}px;
--color1: #000;
--color2: #990;
--color3: #090;
--color4: #099;
}
`
}
</script>
CSS変数を使用したところ、--size
変更後にdiv
サイズはそれに合わせて変化するものの、@keyframes
リズムは変わらず、300の距離でも移動してしまうという問題が発見されました。
これは、@keyframes
定義の時点で固定されており、変数の変更を追跡せず、それに応じて変更されることも意味します。
もちろんレスポンシブアニメーションも問題ありません。トリガーされると、最新の変数値が取得されます。
@media (min-width: 500px) {
:root {
--size: 100px;
--color1: #000;
--color2: #990;
--color3: #090;
--color4: #099;
}
@keyframes play {
0% {
background: var(--color1);
transform: translate(0, 0);
}
25% {
background: var(--color2);
transform: translate(calc(var(--size) / 3), 0);
}
50% {
background: var(--color3);
transform: translate(calc(var(--size) / 3), calc(var(--size) / 3));
}
75% {
background: var(--color4);
transform: translate(0, calc(var(--size) / 3));
}
100% {
background: var(--color1);
transform: translate(0, 0);
}
}
}
@media (min-width: 800px) {
:root {
--size: 300px;
--color1: #000;
--color2: #990;
--color3: #090;
--color4: #099;
}
@keyframes play {
0% {
background: var(--color1);
transform: translate(0, 0);
}
25% {
background: var(--color2);
transform: translate(var(--size), 0);
}
50% {
background: var(--color3);
transform: translate(var(--size), var(--size));
}
75% {
background: var(--color4);
transform: translate(0, var(--size));
}
100% {
background: var(--color1);
transform: translate(0, 0);
}
}
}
@keyframes
ただし、これは動的挿入には使用できません。応答性の高い更新を手動でトリガーする必要があります。良好なエクスペリエンスが必要な場合は、変数を一緒に書き換える必要があります。
JavaScript部分を省略し、固定部分のみを最後に追加
@keyframes
:root {
--size: 300px;
--color1: #000;
--color2: #990;
--color3: #090;
--color4: #099;
}
@keyframes play {
0% {
background: var(--color1);
transform: translate(0, 0);
}
25% {
background: var(--color2);
transform: translate(var(--size), 0);
}
50% {
background: var(--color3);
transform: translate(var(--size), var(--size));
}
75% {
background: var(--color4);
transform: translate(0, var(--size));
}
100% {
background: var(--color1);
transform: translate(0, 0);
}
}
動的タグ
事前に CSS ファイルを作成し、トリガーされたときに HTML に挿入し、オーバーレイを使用して効果を実現します
:root {
--bg-color: #fff;
--text-color: #000;
}
body {
margin: 0;
width: 100vw;
height: 100vh;
font-size: 5em;
text-align: center;
color: var(--text-color);
background: var(--bg-color);
}
body::before {
content: 'light';
}
/* dark.css */
:root {
--bg-color: #000;
--text-color: #fff;
}
body::before {
content: 'dark';
}
document.body.onclick = (() => {
let isDark = false
return () => {
if (isDark) {
const link = document.querySelector("#darkTheme")
link.remove()
} else {
const link = document.createElement('link')
link.id = "darkTheme"
link.rel = "stylesheet"
link.href = "./css/dark.css"
document.head.append(link)
}
isDark = !isDark
}
})()
この方法は非常に簡単で暴力的ではないので、これもお勧めです。
まとめ
CSS 変数の存在によって多くのことが省略されていることがわかります。変数が存在する前に、3 番目の解決策を実装したい場合は、全体を書き直す必要があります。
動的性は CSS-in-JS ソリューションを使用して実現できます@keyframes
が、その実装方法はまだ検討していません。強引に書くより良い解決策はありますか