Toggle navigation
☰
Home
HTML
CSS
Scripting
Database
<!DOCTYPE html> <html lang="en"> <!-- data-theme attribute will be managed by JS --> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Dark Mode & Themed Navbar</title> <style> /* ======================================== CSS Custom Properties for Theming ======================================== The entire theme system is controlled by these variables. The default state (:root) is the light theme. */ :root { --color-background: #f8f9fa; --color-surface: #ffffff; /* Card/Navbar background */ --color-text-primary: #212529; --color-text-secondary: #6c757d; --color-border: #dee2e6; --color-primary: #007bff; --color-primary-hover: #0056b3; --transition-speed: 0.3s; --navbar-height: 70px; --navbar-padding: 1.5rem; --container-width: 1140px; --border-radius: 8px; --font-family-sans-serif: system-ui, -apple-system, sans-serif; } /* The dark theme is an override of the root variables. It is applied when the <html> tag has the `data-theme="dark"` attribute. */ [data-theme="dark"] { --color-background: #121212; --color-surface: #1e1e1e; --color-text-primary: #e0e0e0; --color-text-secondary: #a0a0a0; --color-border: #333333; --color-primary: #3391ff; --color-primary-hover: #5ca8ff; } /* ======================================== Global Styles ======================================== */ *, *::before, *::after { box-sizing: border-box; } body { margin: 0; font-family: var(--font-family-sans-serif); font-size: 1rem; line-height: 1.6; background-color: var(--color-background); color: var(--color-text-primary); transition: background-color var(--transition-speed) ease, color var(--transition-speed) ease; } .content { height: 200vh; padding: 100px var(--navbar-padding); text-align: center; } ul { list-style: none; margin: 0; padding: 0; } a { text-decoration: none; color: var(--color-primary); } a:hover { color: var(--color-primary-hover); } /* ======================================== Navbar Styles ======================================== */ .navbar { height: var(--navbar-height); display: flex; align-items: center; position: sticky; top: 0; background-color: var(--color-surface); border-bottom: 1px solid var(--color-border); transition: background-color var(--transition-speed) ease, border-color var(--transition-speed) ease; z-index: 1000; } .navbar__container { display: flex; justify-content: space-between; align-items: center; width: 100%; max-width: var(--container-width); margin: 0 auto; padding: 0 var(--navbar-padding); } .navbar__brand { font-size: 1.5rem; font-weight: bold; color: var(--color-text-primary); text-decoration: none; transition: color var(--transition-speed) ease; } .navbar__toggle { display: block; border: none; background: transparent; cursor: pointer; padding: 0.5rem; } .navbar__toggle .bar { display: block; width: 25px; height: 3px; margin: 5px auto; background-color: var(--color-text-primary); transition: all var(--transition-speed) ease; } .navbar__toggle.is-active .bar:nth-child(1) { transform: translateY(8px) rotate(45deg); } .navbar__toggle.is-active .bar:nth-child(2) { opacity: 0; } .navbar__toggle.is-active .bar:nth-child(3) { transform: translateY(-8px) rotate(-45deg); } .navbar__menu { display: none; flex-direction: column; width: 100%; position: absolute; top: var(--navbar-height); left: 0; background-color: var(--color-surface); border-bottom: 1px solid var(--color-border); z-index: 999; } .navbar__menu.is-active { display: flex; } .navbar__item { text-align: center; border-top: 1px solid var(--color-border); } .navbar__link { display: block; padding: 1.25rem; font-weight: bold; } /* Focus state for all interactive elements */ :is(.navbar__toggle, .navbar__link, #theme-toggle):focus-visible { outline: 2px solid var(--color-primary); outline-offset: 3px; border-radius: 4px; } /* ======================================== Theme Toggle Button Styles ======================================== */ #theme-toggle { background: none; border: none; cursor: pointer; padding: 0.5rem; border-radius: 50%; display: flex; align-items: center; } .theme-icon { width: 24px; height: 24px; color: var(--color-text-secondary); transition: color var(--transition-speed) ease, transform var(--transition-speed) ease; } #theme-toggle:hover .theme-icon, #theme-toggle:focus .theme-icon { color: var(--color-text-primary); transform: rotate(15deg); } /* Logic to show the correct icon based on the current theme */ .sun-icon { display: none; } .moon-icon { display: block; } [data-theme="dark"] .sun-icon { display: block; } [data-theme="dark"] .moon-icon { display: none; } /* ======================================== Desktop Navbar Styles ======================================== */ @media (min-width: 768px) { .navbar__toggle { display: none; } .navbar__menu { display: flex; flex-direction: row; align-items: center; position: static; width: auto; background-color: transparent; border: none; } .navbar__list { display: flex; align-items: center; gap: 1rem; } .navbar__item { border-top: none; } .navbar__link { padding: 0.5rem; } /* The theme toggle is the last item in the list */ .navbar__item:last-child { margin-left: 1.5rem; } } </style> </head> <body> <!-- FOUC PREVENTION SCRIPT: This runs instantly before the page content is rendered to set the theme, preventing a "flash of unstyled content" if the user has a saved or OS-level preference for a non-default theme. --> <script> (function() { const theme = localStorage.getItem('theme') || (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'); if (theme === 'dark') { document.documentElement.setAttribute('data-theme', 'dark'); } })(); </script> <header class="navbar"> <div class="navbar__container"> <a href="#" class="navbar__brand">Brand</a> <button class="navbar__toggle" id="navbarToggle" aria-label="Toggle navigation" aria-controls="navbarMenu" aria-expanded="false"> <span class="bar"></span><span class="bar"></span><span class="bar"></span> </button> <nav id="navbarMenu" class="navbar__menu" role="navigation"> <ul class="navbar__list"> <li class="navbar__item"><a href="#" class="navbar__link">Home</a></li> <li class="navbar__item"><a href="#" class="navbar__link">Features</a></li> <li class="navbar__item"><a href="#" class="navbar__link">Pricing</a></li> <li class="navbar__item"> <button id="theme-toggle" aria-label="Toggle light and dark theme"> <!-- Sun Icon for switching to Light Mode --> <svg class="theme-icon sun-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12Zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8Z M11 1h2v3h-2V1Zm0 19h2v3h-2v-3ZM20.414 4.929l-1.414-1.414L17.586 5L19 6.414l1.414-1.485ZM3.586 19.001l1.414 1.414L6.414 19l-1.414-1.414-1.414 1.414ZM23 11v2h-3v-2h3ZM4 11v2H1v-2h3ZM17.586 19l1.414-1.414-1.414-1.414-1.414 1.414 1.414 1.414Z"/></svg> <!-- Moon Icon for switching to Dark Mode --> <svg class="theme-icon moon-icon" xmlns="http://www.w.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2ZM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8Z M13.5 12c0-3.08-1.57-5.8-4-7.44C12.42 3.5 16.53 7.03 16.53 12s-4.11 8.5-7.03 9.44c2.43-1.64 4-4.37 4-7.44Z"/></svg> </button> </li> </ul> </nav> </div> </header> <main class="content"> <h1>Page Content</h1> <p>This whole page, not just the navbar, changes theme!</p> </main> <script> // This main script runs after the DOM is ready. document.addEventListener('DOMContentLoaded', function () { // --- Mobile Menu Toggle --- const navbarToggle = document.getElementById('navbarToggle'); const navbarMenu = document.getElementById('navbarMenu'); if (navbarToggle) { navbarToggle.addEventListener('click', function () { navbarToggle.classList.toggle('is-active'); navbarMenu.classList.toggle('is-active'); }); } // --- Theme Toggling Logic --- const themeToggle = document.getElementById('theme-toggle'); const htmlElement = document.documentElement; if (themeToggle) { themeToggle.addEventListener('click', function() { // Check current theme const currentTheme = htmlElement.getAttribute('data-theme'); // Determine the new theme const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; // Set the new theme htmlElement.setAttribute('data-theme', newTheme); // Save the new theme to localStorage localStorage.setItem('theme', newTheme); }); } }); </script> </body> </html>