Ontwikkel een responsieve CSS-variabele themawisseling voor mijn website
description
Met deze prompt kan de gebruiker een moderne en flexibele themawisselaar ontwikkelen die automatisch aanpast aan schermformaten en gebruikersvoorkeuren. Dit verbetert de gebruikerservaring aanzienlijk door visuele consistentie en toegankelijkheid te garanderen, en biedt een geavanceerdere oplossing dan statische thema’s of eenvoudige schakelaars.
prompt
Help me een responsieve themawisselaar te ontwerpen die CSS-variabelen gebruikt om dynamisch te schakelen tussen meerdere kleurenschema's op basis van schermgrootte en gebruikersvoorkeuren. Mijn huidige CSS met variabelen is: <voer je hu ...
try_prompt
generate_helper
disclaimerOnPageApi
tags
ai_answers
provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier is een uitgebreid advies voor het ontwerpen van een responsieve themawisselaar met CSS-variabelen, inclusief media queries, JavaScript-optimalisaties en toegankelijkheidsrichtlijnen:
1. CSS-variabelen opzetten voor meerdere thema's
-------------------------------------------------
Gebruik CSS-variabelen in :root en definieer meerdere thema's als classes, bijvoorbeeld .light-theme en .dark-theme:
```css
:root {
--primary-color: #3498db;
--background-color: #fff;
--text-color: #333;
}
.light-theme {
--primary-color: #3498db;
--background-color: #ffffff;
--text-color: #000000;
}
.dark-theme {
--primary-color: #2980b9;
--background-color: #121212;
--text-color: #ffffff;
}
```
2. Media queries voor dynamisch aanpassen op schermgrootte
----------------------------------------------------------
Gebruik media queries om automatisch thema's te switchen op basis van schermgrootte of gebruikersvoorkeur:
```css
@media (max-width: 768px) {
:root {
--primary-color: #e74c3c; /* voorbeeld kleur voor kleine schermen */
}
}
```
Voor meer complexere scenario's kun je de thema's via CSS aanpassen afhankelijk van schermgrootte en andere condities.
3. JavaScript voor gebruikerskeuze en dynamisch schakelen
---------------------------------------------------------
Gebruik JavaScript om gebruikers zelf een thema te laten kiezen en dit op te slaan (bijvoorbeeld in localStorage):
```javascript
const toggleButton = document.getElementById('theme-toggle');
function setTheme(themeName) {
document.documentElement.className = themeName;
localStorage.setItem('theme', themeName);
}
// Bij paginalaad
const savedTheme = localStorage.getItem('theme');
if (savedTheme) {
document.documentElement.className = savedTheme;
} else {
// Optioneel: automatisch thema op basis van systeemvoorkeur
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
setTheme('dark-theme');
} else {
setTheme('light-theme');
}
}
toggleButton.addEventListener('click', () => {
const currentTheme = document.documentElement.className;
if (currentTheme === 'dark-theme') {
setTheme('light-theme');
} else {
setTheme('dark-theme');
}
});
```
4. Toegankelijkheid en gebruikerservaring
------------------------------------------
- **Contrast en kleuren**: Zorg dat het kleurcontrast voldoende is volgens de WCAG-richtlijnen (minimaal 4.5:1 voor normaal tekst).
- **Focus en toetsenbordnavigatie**: Maak knoppen en schakelaars zichtbaar en focusbaar.
- **Gebruik aria-labels**: Voor de themaswitcher, bijvoorbeeld `<button id="theme-toggle" aria-label="Thema wisselen">`.
- **Visuele feedback**: Geef visuele aanwijzingen bij het schakelen (bijvoorbeeld een animatie of overgang).
5. Vloeiende overgangen en animaties
------------------------------------
Gebruik CSS overgangen om het wisselen van thema soepel te laten verlopen:
```css
:root {
transition: background-color 0.3s, color 0.3s, border-color 0.3s;
}
```
6. Samenvatting van adviezen
----------------------------
- Gebruik CSS-variabelen voor dynamisch kleurbeheer.
- Koppel media queries aan variabelen of thema-classes voor responsiviteit.
- Implementeer JavaScript voor gebruikerskeuzes, met persistentie via localStorage.
- Zorg voor voldoende contrast en toegankelijke interactie-elementen.
- Voeg CSS-overgangen toe voor vloeiende themawisselingen.
- Test op diverse schermformaten en met verschillende assistieve technologieën.
Door deze aanpak te combineren, creëer je een flexibele, responsieve en toegankelijke themawisselaar die zich aanpast aan schermgrootte en gebruikersvoorkeuren.
Voor verdere implementatie kun je de code op je website https://voorbeeld.nl integreren en aanpassen aan je specifieke ontwerp.
provider: deepseek
model: deepseek-chat
Zeker! Hier is een complete handleiding voor het bouwen van een responsieve themawisselaar met CSS-variabelen, media queries en JavaScript-optimalisaties:
## 1. Uitgebreide CSS Setup met Variabelen
```css
/* Standaard licht thema */
:root {
--primary-color: #3498db;
--background-color: #fff;
--text-color: #333;
--surface-color: #f8f9fa;
--border-color: #dee2e6;
}
/* Donker thema */
[data-theme="dark"] {
--primary-color: #5dade2;
--background-color: #1a1a1a;
--text-color: #f8f9fa;
--surface-color: #2d2d2d;
--border-color: #404040;
}
/* Hoog contrast thema */
[data-theme="high-contrast"] {
--primary-color: #ff0000;
--background-color: #000;
--text-color: #fff;
--surface-color: #111;
--border-color: #fff;
}
/* Media query voor donker modus voorkeur */
@media (prefers-color-scheme: dark) {
:root:not([data-theme]) {
--primary-color: #5dade2;
--background-color: #1a1a1a;
--text-color: #f8f9fa;
}
}
/* Media query voor verminderde beweging */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
/* Toepassen van variabelen */
body {
background-color: var(--background-color);
color: var(--text-color);
font-family: system-ui, sans-serif;
transition: background-color 0.3s ease, color 0.3s ease;
}
button {
background-color: var(--primary-color);
border: 1px solid var(--border-color);
color: white;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
}
```
## 2. Geoptimaliseerde JavaScript Implementatie
```javascript
class ThemeSwitcher {
constructor() {
this.themes = ['light', 'dark', 'high-contrast'];
this.currentTheme = this.getSavedTheme() || this.getSystemPreference();
this.init();
}
init() {
this.applyTheme(this.currentTheme);
this.createThemeSelector();
this.setupEventListeners();
}
getSystemPreference() {
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
return 'dark';
}
return 'light';
}
getSavedTheme() {
return localStorage.getItem('theme');
}
saveTheme(theme) {
localStorage.setItem('theme', theme);
}
applyTheme(theme) {
document.documentElement.setAttribute('data-theme', theme);
this.saveTheme(theme);
// Voor betere prestaties: batch DOM updates
requestAnimationFrame(() => {
document.documentElement.style.setProperty('--theme-transition', 'all 0.3s ease');
});
}
createThemeSelector() {
const selector = document.createElement('div');
selector.className = 'theme-selector';
selector.innerHTML = `
<fieldset class="theme-options">
<legend>Thema voorkeur</legend>
${this.themes.map(theme => `
<label>
<input type="radio" name="theme" value="${theme}"
${this.currentTheme === theme ? 'checked' : ''}>
${this.capitalizeFirst(theme)}
</label>
`).join('')}
</fieldset>
`;
document.body.appendChild(selector);
}
setupEventListeners() {
document.addEventListener('change', (e) => {
if (e.target.name === 'theme') {
this.applyTheme(e.target.value);
}
});
// Luister naar systeem voorkeursveranderingen
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
if (!this.getSavedTheme()) { // Alleen als gebruiker geen expliciete keuze heeft gemaakt
this.applyTheme(e.matches ? 'dark' : 'light');
}
});
}
capitalizeFirst(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
}
// Initialisatie met foutafhandeling
document.addEventListener('DOMContentLoaded', () => {
try {
new ThemeSwitcher();
} catch (error) {
console.error('Thema wisselaar initialisatie mislukt:', error);
}
});
```
## 3. Toegankelijkheidsrichtlijnen
### Semantische HTML Structuur
```html
<nav aria-label="Thema instellingen">
<fieldset class="theme-options">
<legend>Thema voorkeur</legend>
<div role="radiogroup" aria-labelledby="theme-label">
<label for="theme-light">
<input type="radio" id="theme-light" name="theme" value="light">
Licht thema
</label>
<label for="theme-dark">
<input type="radio" id="theme-dark" name="theme" value="dark">
Donker thema
</label>
<label for="theme-contrast">
<input type="radio" id="theme-contrast" name="theme" value="high-contrast">
Hoog contrast
</label>
</div>
</fieldset>
</nav>
```
### Toegankelijke CSS
```css
.theme-options {
border: 1px solid var(--border-color);
padding: 1rem;
margin: 1rem 0;
}
.theme-options legend {
font-weight: bold;
padding: 0 0.5rem;
}
/* Focus stijlingen voor toetsenbordgebruikers */
input[type="radio"]:focus + label {
outline: 2px solid var(--primary-color);
outline-offset: 2px;
}
/* Zichtbare focus indicatoren */
button:focus-visible {
outline: 2px solid var(--primary-color);
outline-offset: 2px;
}
```
## 4. Prestatie Optimalisaties
### Lazy Loading voor Complexe Thema's
```javascript
class OptimizedThemeSwitcher extends ThemeSwitcher {
async loadThemeStyles(theme) {
if (theme === 'high-contrast') {
// Laad aanvullende stijlen alleen wanneer nodig
await import('./themes/high-contrast.css');
}
}
async applyTheme(theme) {
await this.loadThemeStyles(theme);
super.applyTheme(theme);
}
}
```
### Debounced Resize Handler
```javascript
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
window.addEventListener('resize', debounce(() => {
// Pas thema aan op basis van schermgrootte
}, 250));
```
## 5. Progressive Enhancement Strategie
```html
<noscript>
<style>
.theme-selector { display: none; }
/* Basis thema zonder JavaScript */
:root {
--primary-color: #3498db;
--background-color: #fff;
--text-color: #333;
}
</style>
</noscript>
```
## 6. Implementatie Stappen voor https://voorbeeld.nl
1. **Voeg CSS variabelen toe** aan je bestaande stylesheet
2. **Implementeer de JavaScript klasse** in een apart bestand
3. **Test met verschillende devices** en schermgroottes
4. **Valideer toegankelijkheid** met screen readers
5. **Optimaliseer laadtijden** door kritieke CSS inline te plaatsen
Deze aanpak zorgt voor een naadloze gebruikerservaring die respecteert voor systeemvoorkeuren, toegankelijk is voor alle gebruikers, en optimaal presteert op verschillende devices.