Theming
WebF automatically detects and synchronizes with Flutter’s system theme. Your WebF app will automatically receive color scheme updates when the system theme changes.
Automatic Theme Synchronization (Default Behavior)
WebF automatically watches Flutter’s MediaQuery theme changes and updates the WebF app accordingly:
// No manual setup needed - WebF automatically syncs with system theme
MaterialApp(
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
themeMode: ThemeMode.system, // WebF will automatically follow system changes
home: WebF.fromControllerName(
controllerName: 'app',
),
)When the system theme changes (light ↔ dark), WebF automatically:
- Updates the
prefers-color-schememedia query - Dispatches
'colorschemchange'event to JavaScript - Re-evaluates CSS with the new color scheme
Manual Theme Override (Advanced)
Use darkModeOverride when you need to override the automatic behavior with a user preference from your app’s settings:
WebFController? _controller;
// When user manually changes theme preference in your app's settings
void onUserThemePreferenceChanged(bool userPrefersDark) {
_controller?.darkModeOverride = userPrefersDark;
// This overrides automatic theme detection
// Useful when users have in-app theme selection (Light/Dark/Auto)
}
// Example: User selects "Always Dark" in app settings
ElevatedButton(
onPressed: () {
onUserThemePreferenceChanged(true);
},
child: Text('Force Dark Mode'),
)When to use darkModeOverride:
- Your app has user-facing theme selection (Light/Dark/Auto)
- You want to override system theme based on user preference
- You need to force a specific theme for testing
When NOT to use darkModeOverride:
- For normal system theme synchronization (WebF handles this automatically)
- When you just want to follow Flutter’s theme (default behavior)
In Your WebF App (CSS)
Respond to theme changes using CSS media queries:
/* Light theme styles */
@media (prefers-color-scheme: light) {
body {
background-color: #ffffff;
color: #000000;
}
.card {
background-color: #f5f5f5;
border: 1px solid #e0e0e0;
}
}
/* Dark theme styles */
@media (prefers-color-scheme: dark) {
body {
background-color: #1e1e1e;
color: #ffffff;
}
.card {
background-color: #2d2d2d;
border: 1px solid #3d3d3d;
}
}In Your WebF App (JavaScript)
Listen for theme changes and update your UI accordingly:
// Check current theme
const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
console.log(`Current theme: ${isDarkMode ? 'dark' : 'light'}`);
// Listen for theme changes
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
if (e.matches) {
console.log('Switched to dark mode');
document.body.classList.add('dark');
} else {
console.log('Switched to light mode');
document.body.classList.remove('dark');
}
});React Example
Using theme detection in a React component:
import { useState, useEffect } from 'react';
function App() {
const [isDark, setIsDark] = useState(
window.matchMedia('(prefers-color-scheme: dark)').matches
);
useEffect(() => {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handleChange = (e) => {
setIsDark(e.matches);
};
mediaQuery.addEventListener('change', handleChange);
return () => {
mediaQuery.removeEventListener('change', handleChange);
};
}, []);
return (
<div className={isDark ? 'dark-theme' : 'light-theme'}>
<h1>Current theme: {isDark ? 'Dark' : 'Light'}</h1>
</div>
);
}Tailwind CSS Integration
Tailwind CSS has built-in support for dark mode using prefers-color-scheme:
// tailwind.config.js
module.exports = {
darkMode: 'media', // Uses prefers-color-scheme media query
// ... rest of config
}
// Usage in components
function Card() {
return (
<div className="bg-white dark:bg-gray-800 text-black dark:text-white">
<h2 className="text-xl dark:text-gray-100">Card Title</h2>
<p className="text-gray-600 dark:text-gray-400">Card content</p>
</div>
);
}Best Practices
-
Use CSS Variables: Define theme colors with CSS variables for easier management:
:root { --bg-primary: #ffffff; --text-primary: #000000; } @media (prefers-color-scheme: dark) { :root { --bg-primary: #1e1e1e; --text-primary: #ffffff; } } body { background-color: var(--bg-primary); color: var(--text-primary); } -
Test Both Themes: Always test your app in both light and dark modes to ensure good contrast and readability.
-
Respect User Preferences: Use automatic synchronization by default and only override when users explicitly choose a theme preference in your app settings.
-
Smooth Transitions: Add transitions for theme changes:
* { transition: background-color 0.3s ease, color 0.3s ease; }
Next Steps
- Performance Monitoring - Track loading performance
- Caching - Optimize network requests
- API Reference - View complete API documentation