Skip to Content

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:

  1. Updates the prefers-color-scheme media query
  2. Dispatches 'colorschemchange' event to JavaScript
  3. 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

  1. 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); }
  2. Test Both Themes: Always test your app in both light and dark modes to ensure good contrast and readability.

  3. Respect User Preferences: Use automatic synchronization by default and only override when users explicitly choose a theme preference in your app settings.

  4. Smooth Transitions: Add transitions for theme changes:

    * { transition: background-color 0.3s ease, color 0.3s ease; }

Next Steps