ダーク モードの切り替えを実装するのに何時間も費やした結果、ページの更新時に目がくらむほど白く点滅したことはありませんか?それともさらに悪いことに、ユーザーのシステム設定を完全に無視しているのでしょうか?はい、私もです。 ?
ここで重要なのは、ダークモードはもはや単なる流行の機能ではないということです。夜間にコーディングする人が増え(有罪となります)、アクセシビリティの重要性がますます高まっているため、適切に実装されたダーク モードは、最新の Web サイトや Web アプリには実質的に必須となっています。しかし、正しく理解するのは驚くほど難しい場合があります。
良い知らせですか?さまざまな実装を手探りし、localStorage と格闘した結果、最終的に次のようなダーク モード切り替えのコードを解読しました。
この投稿では、実際に使用するダーク モード トグルの構築について説明します。過度に複雑なソリューションや不要な依存関係はなく、すぐに実装できるクリーンで動作するコードだけです。
最初に退屈な部分を片付けましょう - ただし、短くすることを約束します!
必要なものはすでにすべて揃っていると思いますが、同じ認識を持っていることを確認してください:
本題に入る前に、最終的にどうなるかを簡単に見てみましょう。派手な UI ライブラリや複雑なセットアップは必要ありません。次のようなシンプルでスムーズな切り替えだけです:
このようにまったく同じように見せることについて心配する必要はありません。重要なのは、完璧に動作するということです。まず機能に焦点を当てますが、その後は自由にスタイルを設定できます。
一番良かった点は?これから構築しようとしているものはすべて次のもので動作します:
実際に手を動かす準備はできていますか?まずは基礎から始めましょう!
さて、実際にやってみましょう!まず、基本的な構造を設定します。
非常に単純な HTML から始めます。この部分については深く考える必要はありません:
<button> <h3> The CSS </h3> <p>Here's where things get interesting. We'll use CSS variables (aka custom properties) to handle our color scheme. Drop this in your CSS file:<br> </p> <pre class="brush:php;toolbar:false">:root { --background: #ffffff; --text-primary: #222222; --toggle-bg: #e4e4e7; --toggle-hover: #d4d4d8; } [data-theme="dark"] { --background: #121212; --text-primary: #ffffff; --toggle-bg: #3f3f46; --toggle-hover: #52525b; } body { background-color: var(--background); color: var(--text-primary); transition: background-color 0.3s ease, color 0.3s ease; height: 100vh; display: flex; align-items: center; justify-content: center; } .theme-toggle { border: none; padding: 0.5rem; border-radius: 9999px; background-color: var(--toggle-bg); cursor: pointer; transition: background-color 0.2s ease; align-self: flex-start; position: absolute; right: 20px; } .theme-toggle:hover { background-color: var(--toggle-hover); } .theme-toggle svg { transform-origin: center; transition: transform 0.3s ease; } .theme-toggle:active svg { transform: rotate(30deg); } h1 { display: flex; } .sun-icon { display: none; width: 24px; height: 24px; } .moon-icon { width: 24px; height: 24px; } [data-theme="dark"] .sun-icon { display: block; } [data-theme="dark"] .moon-icon { display: none; }
プロのヒント: クラスの代わりにデータテーマを使用していることに気づきましたか?これにより、属性の目的が非常に明確になり、潜在的なクラス名の競合が防止されます。
アイコンについては、独自の SVG を使用することも、お気に入りのアイコン ライブラリから取得することもできます。私はシンプルなものを使用するのが好きなので、Chatgpt にこれを考え出すように言いました:
<!-- Replace the empty SVGs with these --> <svg> <p>At this point, your toggle should look pretty decent, but it won't actually do anything yet. Don't worry though - in the next section, we'll add the JavaScript that makes it all work!</p> <p><strong>A quick heads-up:</strong> I've kept the styling minimal on purpose. Feel free to spice it up with your own creative touches. Want a sliding animation? Go for it! Prefer a different icon style? Make it yours!</p> <p>Ready to make this thing actually work? Let's move on to the JavaScript implementation!</p> <h2> The JavaScript Implementation (Where It All Comes Together!) </h2> <p>Alright, this is where we make our toggle actually, you know... toggle. But don't worry - we're keeping it clean and simple.<br> </p> <pre class="brush:php;toolbar:false">const themeToggle = document.querySelector('.theme-toggle'); function toggleTheme() { const currentTheme = document.documentElement.getAttribute('data-theme'); const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; document.documentElement.setAttribute('data-theme', newTheme); localStorage.setItem('theme', newTheme); } // Listen for clicks on our toggle themeToggle.addEventListener('click', toggleTheme); function initializeTheme() { const savedTheme = localStorage.getItem('theme'); if (savedTheme) { document.documentElement.setAttribute('data-theme', savedTheme); } else { const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; document.documentElement.setAttribute( 'data-theme', prefersDark ? 'dark' : 'light' ); localStorage.setItem('theme', prefersDark ? 'dark' : 'light'); } } // Run on page load initializeTheme(); // Listen for system theme change window.matchMedia('(prefers-color-scheme: dark)') .addEventListener('change', (e) => { // Only update if user hasn't manually set a preference if (!localStorage.getItem('theme')) { document.documentElement.setAttribute( 'data-theme', e.matches ? 'dark' : 'light' ); } });
実際に非常に素晴らしいことが起こっているので、ここで何が起こっているのかを詳しく見てみましょう:
これは一般的な問題です。ページが読み込まれるときに、ユーザーに間違ったテーマのフラッシュが表示されることがあります。とても迷惑ですよね?このスクリプトを
に追加してこの問題を修正しましょう。 HTML の:<script> // Add this to your <head> before any style sheets (function() { const savedTheme = localStorage.getItem('theme'); if (savedTheme) { document.documentElement.setAttribute('data-theme', savedTheme); } else if (window.matchMedia('(prefers-color-scheme: dark)').matches) { document.documentElement.setAttribute('data-theme', 'dark'); } })(); </script>
これは、他のものが読み込まれる直前に実行され、煩わしいフラッシュを防ぎます。
そして...それだけです!ダークモードの切り替えが機能し、次のことが可能になりました:
さらに改善したいですか?良い状態から素晴らしい状態に切り替えるための役立つヒントに移りましょう!
重要だが見落とされがちな改善点をいくつか挙げて、「うまく機能する」から「美しく機能する」に切り替えてみましょう。これらは、専門的な実装と簡単なハックを区別する種類の詳細です。
まず、デバイスの操作方法に関係なく、誰もがトグルを使用できることを確認しましょう。
// Add this to your existing JavaScript themeToggle.addEventListener('keydown', (e) => { // Toggle on Enter or Space if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggleTheme(); } });
ユーザーが動きを減らしたい場合はトランジションを無効にします:
@media (prefers-reduced-motion: reduce) { body { transition: none; } }
多くの開発者が見逃している点があります。一部のコンテンツはテーマに基づいて変更する必要がある場合があります。ライト/ダーク モードの異なるバージョンの画像について考えてみましょう:
// Add this to your toggleTheme function function updateThemeSpecificContent(theme) { // Find all theme-aware images const themeImages = document.querySelectorAll('[data-theme-image]'); themeImages.forEach(img => { const lightSrc = img.getAttribute('data-light-src'); const darkSrc = img.getAttribute('data-dark-src'); img.src = theme === 'dark' ? darkSrc : lightSrc; }); }
次のように HTML で使用します:
<img data-theme-image data-light-src="/path/to/light-logo.png" data-dark-src="/path/to/dark-logo.png" alt="ダークモードトグルを数秒で構築 (実際に機能します)">
保存されたテーマが実際に表示されているものと同期しない場合があります。安全性チェックを追加しましょう:
<button> <h3> The CSS </h3> <p>Here's where things get interesting. We'll use CSS variables (aka custom properties) to handle our color scheme. Drop this in your CSS file:<br> </p> <pre class="brush:php;toolbar:false">:root { --background: #ffffff; --text-primary: #222222; --toggle-bg: #e4e4e7; --toggle-hover: #d4d4d8; } [data-theme="dark"] { --background: #121212; --text-primary: #ffffff; --toggle-bg: #3f3f46; --toggle-hover: #52525b; } body { background-color: var(--background); color: var(--text-primary); transition: background-color 0.3s ease, color 0.3s ease; height: 100vh; display: flex; align-items: center; justify-content: center; } .theme-toggle { border: none; padding: 0.5rem; border-radius: 9999px; background-color: var(--toggle-bg); cursor: pointer; transition: background-color 0.2s ease; align-self: flex-start; position: absolute; right: 20px; } .theme-toggle:hover { background-color: var(--toggle-hover); } .theme-toggle svg { transform-origin: center; transition: transform 0.3s ease; } .theme-toggle:active svg { transform: rotate(30deg); } h1 { display: flex; } .sun-icon { display: none; width: 24px; height: 24px; } .moon-icon { width: 24px; height: 24px; } [data-theme="dark"] .sun-icon { display: block; } [data-theme="dark"] .moon-icon { display: none; }
これは、さまざまなテーマでカスタム フォントを読み込むときにレイアウトのずれを防ぐための巧妙なトリックです:
<!-- Replace the empty SVGs with these --> <svg> <p>At this point, your toggle should look pretty decent, but it won't actually do anything yet. Don't worry though - in the next section, we'll add the JavaScript that makes it all work!</p> <p><strong>A quick heads-up:</strong> I've kept the styling minimal on purpose. Feel free to spice it up with your own creative touches. Want a sliding animation? Go for it! Prefer a different icon style? Make it yours!</p> <p>Ready to make this thing actually work? Let's move on to the JavaScript implementation!</p> <h2> The JavaScript Implementation (Where It All Comes Together!) </h2> <p>Alright, this is where we make our toggle actually, you know... toggle. But don't worry - we're keeping it clean and simple.<br> </p> <pre class="brush:php;toolbar:false">const themeToggle = document.querySelector('.theme-toggle'); function toggleTheme() { const currentTheme = document.documentElement.getAttribute('data-theme'); const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; document.documentElement.setAttribute('data-theme', newTheme); localStorage.setItem('theme', newTheme); } // Listen for clicks on our toggle themeToggle.addEventListener('click', toggleTheme); function initializeTheme() { const savedTheme = localStorage.getItem('theme'); if (savedTheme) { document.documentElement.setAttribute('data-theme', savedTheme); } else { const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; document.documentElement.setAttribute( 'data-theme', prefersDark ? 'dark' : 'light' ); localStorage.setItem('theme', prefersDark ? 'dark' : 'light'); } } // Run on page load initializeTheme(); // Listen for system theme change window.matchMedia('(prefers-color-scheme: dark)') .addEventListener('change', (e) => { // Only update if user hasn't manually set a preference if (!localStorage.getItem('theme')) { document.documentElement.setAttribute( 'data-theme', e.matches ? 'dark' : 'light' ); } });
出荷する前に、次のシナリオを必ずテストしてください:
<script> // Add this to your <head> before any style sheets (function() { const savedTheme = localStorage.getItem('theme'); if (savedTheme) { document.documentElement.setAttribute('data-theme', savedTheme); } else if (window.matchMedia('(prefers-color-scheme: dark)').matches) { document.documentElement.setAttribute('data-theme', 'dark'); } })(); </script>
// Add this to your existing JavaScript themeToggle.addEventListener('keydown', (e) => { // Toggle on Enter or Space if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggleTheme(); } });
それだけです!これで、さまざまなシナリオをチャンピオンのように処理できる、堅牢でアクセスしやすく、ユーザーフレンドリーなダーク モードの実装が完成しました。
さて、これで完成です!私たちは、機能するだけでなく、非常にうまく機能するダーク モード トグルを構築しました。
これまでに達成したことを簡単にまとめてみましょう:
このコードを自由に使用して、独自のものにしてください。派手なアニメーションを追加したり、さまざまな配色を試したり、既存のデザインと統合したりすることもできます。私たちが構築した基盤は、どんな創造的なアイデアを投げかけても対処できるほど強固です。
ダーク モードは細かいことのように思えるかもしれませんが、こうした小さな工夫こそ、ユーザー エクスペリエンスを重視していることを示しています。それに、とにかくかっこいいんです。優れたダークモードが気に入らない人はいないでしょうか?
これが役立つと思われた場合は、他の開発者と自由に共有してください。また、何か素晴らしい改善点を思いついた場合は、ぜひお知らせください!
このガイドが気に入って、さらに Web 開発のヒントやハック、プログラミングに関するお父さんのジョークがもっと知りたい場合は、X で私と一緒に遊びに来てください!私の開発者の経験から得た簡単なヒント、コーディングに関する洞察、実際のソリューションを共有します。
? @Peboydcoder
をフォローしてください私は以下について定期的に投稿しています:
お立ち寄りください!より良い Web エクスペリエンスの構築に関心を持つ開発者仲間とつながるのをいつも楽しみにしています。
以上がダークモードトグルを数秒で構築 (実際に機能します)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。