Compare commits

...

2 Commits

Author SHA1 Message Date
ben7sys
d4f33346ed theme toggle problems 2024-11-17 06:49:19 +01:00
ben7sys
4330dfe0c7 gpu acceleration 2024-11-17 06:40:03 +01:00
6 changed files with 135 additions and 11 deletions

View File

@@ -39,4 +39,61 @@ Improved event handling
Enhanced error handling Enhanced error handling
Better organization of CSS media queries Better organization of CSS media queries
Added proper touch device detection Added proper touch device detection
All changes maintain existing functionality while improving user experience, accessibility, and performance. The mobile menu now behaves more naturally, with proper closing behavior and smooth transitions. All changes maintain existing functionality while improving user experience, accessibility, and performance. The mobile menu now behaves more naturally, with proper closing behavior and smooth transitions.
---
Current Implementation Analysis:
Theme System Architecture
CSS Variables (variables.css): ✓ Well-structured light/dark theme variables ✓ Logical separation of common tokens ✓ Clear naming conventions ✓ Efficient use of CSS custom properties
Theme Switching (theme.js):
Robust Implementation: ✓ IIFE for encapsulation ✓ Early initialization prevents FOUC ✓ System theme preference detection ✓ Local storage persistence ✓ Comprehensive error handling
CSS Structure:
Modular Organization: ✓ Separate files for different concerns ✓ Clean inheritance patterns ✓ Proper cascade management ✓ Efficient variable usage
Integration:
Clean Component Integration: ✓ Theme toggle properly placed in header ✓ Smooth transitions between themes ✓ Proper script/style loading order
Strengths to Preserve:
The modular CSS architecture
The CSS variables-based theming approach
The early theme initialization
The system preference detection
Minor Optimization Suggestions:
Theme Switching Performance:
/* Add to variables.css */
:root {
/* Add GPU acceleration for theme transitions */
--theme-transition: color var(--transition-speed) ease,
background-color var(--transition-speed) ease;
--gpu-accelerated: translate3d(0, 0, 0);
}
Theme Toggle Accessibility:
/* Add to header.css */
.theme-toggle:focus-visible {
outline: 2px solid var(--primary);
outline-offset: 2px;
border-radius: var(--border-radius);
}
Theme Persistence Enhancement:
// Add to theme.js persistTheme function
function persistTheme() {
try {
const currentTheme = getCurrentTheme();
localStorage.setItem(THEME_STORAGE_KEY, currentTheme);
// Add theme to body for better SSR support
document.body.dataset.theme = currentTheme;
} catch (error) {
console.warn('Theme persistence error:', error);
}
}
These suggestions maintain the existing architecture while adding:
Improved performance through GPU acceleration
Enhanced accessibility
Better server-side rendering support
The current implementation is well-structured and follows best practices. The suggested optimizations are minimal and non-invasive, preserving the existing functionality while making subtle improvements to performance and accessibility.

View File

@@ -11,6 +11,7 @@
<a href="#services" id="expertise-link">Expertise</a> <a href="#services" id="expertise-link">Expertise</a>
<a href="#contact" id="contact-link">Kontakt</a> <a href="#contact" id="contact-link">Kontakt</a>
<button class="theme-toggle" aria-label="Theme Toggle"> <button class="theme-toggle" aria-label="Theme Toggle">
<i class="fas fa-sun"></i>
<i class="fas fa-moon"></i> <i class="fas fa-moon"></i>
</button> </button>
</nav> </nav>

View File

@@ -5,8 +5,9 @@
} }
html { html {
height: 100%;
transition: color var(--transition-speed) ease, transition: color var(--transition-speed) ease,
background-color var(--transition-speed) ease; background-color var(--transition-speed) ease;
} }
body { body {
@@ -15,6 +16,8 @@ body {
color: var(--text); color: var(--text);
line-height: 1.6; line-height: 1.6;
min-height: 100vh; min-height: 100vh;
transition: var(--theme-transition);
will-change: background-color, color;
} }
h1 { h1 {
@@ -23,17 +26,20 @@ h1 {
color: var(--text); color: var(--text);
opacity: 0.85; opacity: 0.85;
font-weight: 600; font-weight: 600;
transition: var(--theme-transition);
} }
h2 { h2 {
font-size: 2rem; font-size: 2rem;
margin-bottom: var(--spacing-lg); margin-bottom: var(--spacing-lg);
color: var(--text); color: var(--text);
transition: var(--theme-transition);
} }
h3 { h3 {
color: var(--text); color: var(--text);
margin-bottom: var(--spacing-md); margin-bottom: var(--spacing-md);
transition: var(--theme-transition);
} }
h1.h1-hero { h1.h1-hero {
@@ -48,12 +54,13 @@ h1.h1-hero {
p { p {
margin-bottom: var(--spacing-md); margin-bottom: var(--spacing-md);
transition: var(--theme-transition);
} }
a { a {
color: var(--primary); color: var(--primary);
text-decoration: none; text-decoration: none;
transition: opacity var(--transition-speed) ease; transition: var(--theme-transition), opacity var(--transition-speed) ease;
} }
a:hover { a:hover {

View File

@@ -10,8 +10,9 @@ header {
left: 0; left: 0;
right: 0; right: 0;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
transition: background-color 0.7s ease, transform 0.7s ease, box-shadow 0.7s ease; transition: var(--theme-transition), transform 0.7s ease, box-shadow 0.7s ease;
max-height: var(--header-height); max-height: var(--header-height);
transform: var(--gpu-accelerated);
} }
.header-content { .header-content {
@@ -45,13 +46,14 @@ header {
display: flex; display: flex;
gap: var(--spacing-lg); gap: var(--spacing-lg);
align-items: center; align-items: center;
padding-top: 16px;
} }
.nav-menu a { .nav-menu a {
color: var(--text); color: var(--text);
text-decoration: none; text-decoration: none;
font-size: 1rem; font-size: 1rem;
transition: color var(--transition-speed) ease; transition: var(--theme-transition);
} }
.nav-menu a:hover { .nav-menu a:hover {
@@ -67,11 +69,58 @@ header {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
transition: color var(--transition-speed) ease; transition: var(--theme-transition);
border-radius: var(--border-radius);
position: relative;
width: 40px;
height: 40px;
margin-left: var(--spacing-sm);
} }
.theme-toggle:hover { .theme-toggle:hover {
color: var(--primary); color: var(--primary);
background-color: var(--bg-card);
}
.theme-toggle:focus-visible {
outline: 2px solid var(--primary);
outline-offset: 2px;
border-radius: var(--border-radius);
}
.theme-toggle i {
font-size: 1.2rem;
position: absolute;
transition: opacity var(--transition-speed) ease,
transform var(--transition-speed) ease;
transform: var(--gpu-accelerated);
}
/* Light Theme Icon States */
[data-theme="light"] .theme-toggle .fa-moon {
opacity: 1;
transform: rotate(0) var(--gpu-accelerated);
}
[data-theme="light"] .theme-toggle .fa-sun {
opacity: 0;
transform: rotate(-90deg) var(--gpu-accelerated);
}
/* Dark Theme Icon States */
[data-theme="dark"] .theme-toggle .fa-moon {
opacity: 0;
transform: rotate(90deg) var(--gpu-accelerated);
}
[data-theme="dark"] .theme-toggle .fa-sun {
opacity: 1;
transform: rotate(0) var(--gpu-accelerated);
}
/* Hover Animation */
.theme-toggle:hover i {
transform: rotate(15deg) var(--gpu-accelerated);
} }
.mobile-menu-toggle { .mobile-menu-toggle {
@@ -82,4 +131,3 @@ header {
cursor: pointer; cursor: pointer;
padding: var(--spacing-sm); padding: var(--spacing-sm);
} }

View File

@@ -33,4 +33,9 @@
--border-radius: 8px; --border-radius: 8px;
--transition-speed: 0.3s; --transition-speed: 0.3s;
--header-height: 140px; --header-height: 140px;
/* Theme transition with GPU acceleration */
--theme-transition: color var(--transition-speed) ease,
background-color var(--transition-speed) ease;
--gpu-accelerated: translate3d(0, 0, 0);
} }

View File

@@ -26,11 +26,11 @@
// Set initial theme // Set initial theme
const initialTheme = savedTheme || (prefersDark ? THEMES.DARK : THEMES.LIGHT); const initialTheme = savedTheme || (prefersDark ? THEMES.DARK : THEMES.LIGHT);
document.documentElement.setAttribute('data-theme', initialTheme); setTheme(initialTheme);
} catch (error) { } catch (error) {
console.warn('Early theme initialization error:', error); console.warn('Early theme initialization error:', error);
// Fallback to light theme // Fallback to light theme
document.documentElement.setAttribute('data-theme', DEFAULT_THEME); setTheme(DEFAULT_THEME);
} }
} }
@@ -58,12 +58,17 @@
return document.documentElement.getAttribute('data-theme') || DEFAULT_THEME; return document.documentElement.getAttribute('data-theme') || DEFAULT_THEME;
} }
function setTheme(theme) {
document.documentElement.setAttribute('data-theme', theme);
document.body.dataset.theme = theme; // Add theme to body for better SSR support
}
function toggleTheme() { function toggleTheme() {
try { try {
const currentTheme = getCurrentTheme(); const currentTheme = getCurrentTheme();
const newTheme = currentTheme === THEMES.DARK ? THEMES.LIGHT : THEMES.DARK; const newTheme = currentTheme === THEMES.DARK ? THEMES.LIGHT : THEMES.DARK;
document.documentElement.setAttribute('data-theme', newTheme); setTheme(newTheme);
localStorage.setItem(THEME_STORAGE_KEY, newTheme); localStorage.setItem(THEME_STORAGE_KEY, newTheme);
updateThemeIcon(newTheme); updateThemeIcon(newTheme);
} catch (error) { } catch (error) {
@@ -89,7 +94,7 @@
// Only update theme if user hasn't set a preference // Only update theme if user hasn't set a preference
if (!localStorage.getItem(THEME_STORAGE_KEY)) { if (!localStorage.getItem(THEME_STORAGE_KEY)) {
const newTheme = e.matches ? THEMES.DARK : THEMES.LIGHT; const newTheme = e.matches ? THEMES.DARK : THEMES.LIGHT;
document.documentElement.setAttribute('data-theme', newTheme); setTheme(newTheme);
updateThemeIcon(newTheme); updateThemeIcon(newTheme);
} }
} catch (error) { } catch (error) {
@@ -101,6 +106,7 @@
try { try {
const currentTheme = getCurrentTheme(); const currentTheme = getCurrentTheme();
localStorage.setItem(THEME_STORAGE_KEY, currentTheme); localStorage.setItem(THEME_STORAGE_KEY, currentTheme);
document.body.dataset.theme = currentTheme; // Ensure theme is set on body before unload
} catch (error) { } catch (error) {
console.warn('Theme persistence error:', error); console.warn('Theme persistence error:', error);
} }