어두운 모드 토글을 구현하는 데 몇 시간을 소비했지만 페이지 새로 고침 시 눈이 멀 정도로 흰색으로 깜박이게 한 적이 있습니까? 아니면 사용자의 시스템 기본 설정을 완전히 무시했습니까? 응, 나도 마찬가지야. ?
사실입니다. 어두운 모드는 더 이상 유행하는 기능이 아닙니다. 밤에 코딩하는 사람이 늘어나고(유죄) 접근성이 점점 중요해짐에 따라 잘 구현된 다크 모드는 현대 웹사이트나 웹 앱에 사실상 필수입니다. 하지만 이를 올바르게 수행하는 것은 놀라울 정도로 까다로울 수 있습니다.
좋은 소식은요? 다양한 구현을 더듬고 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="inutes에서 다크 모드 토글 구축(실제로 작동함)">
때때로 저장된 테마가 실제로 표시되는 테마와 동기화되지 않을 수 있습니다. 안전 확인을 추가해 보겠습니다.
<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(); } });
그렇습니다! 이제 챔피언과 같은 다양한 시나리오를 처리하는 강력하고 접근 가능하며 사용자 친화적인 다크 모드 구현이 가능해졌습니다.
자, 거기 있어요! 우리는 작동할 뿐만 아니라 정말 잘 작동하는 다크 모드 토글을 구축했습니다.
우리가 성취한 내용을 빠르게 요약해 보겠습니다.
이 코드를 자유롭게 사용하여 나만의 코드로 만들어 보세요. 멋진 애니메이션을 추가하거나, 다양한 색상 구성을 시도하거나, 기존 디자인과 통합할 수도 있습니다. 우리가 구축한 기반은 귀하가 던지는 어떤 창의적인 아이디어도 처리할 수 있을 만큼 견고합니다.
어두운 모드는 작은 세부 사항처럼 보일 수 있지만 이러한 작은 터치를 통해 사용자 경험에 관심을 기울이고 있음을 알 수 있습니다. 게다가 정말 멋지네요. 좋은 다크 모드를 좋아하지 않는 사람이 있을까요?
이 내용이 도움이 되었다면 다른 개발자와 자유롭게 공유해 주세요. 그리고 멋진 개선 사항이 있으면 알려주세요!
이 가이드가 마음에 들었고 더 많은 웹 개발 팁, 해킹, 프로그래밍에 대한 아빠의 농담을 더 알고 싶다면 X에서 저와 함께 놀러 오세요! 개발자 여정에서 얻은 빠른 팁, 코딩 통찰력, 실제 솔루션을 공유합니다.
? @Peboydcoder를 팔로우하세요
다음 주제에 대해 정기적으로 게시합니다.
들러서 인사하세요! 더 나은 웹 경험을 구축하는 데 관심이 있는 동료 개발자들과 소통하는 것은 언제나 즐겁습니다.
위 내용은 inutes에서 다크 모드 토글 구축(실제로 작동함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!