Flutter applies styling in a strict hierarchy: styles applied to the specific widget -> themes that override the immediate parent theme -> the main app theme.
Define app-wide themes using the theme property of MaterialApp with a ThemeData instance.
Override themes for specific widget subtrees by wrapping them in a Theme widget and using Theme.of(context).copyWith(...).
Do not use deprecated ThemeData properties:
Replace accentColor with colorScheme.secondary.
Replace accentTextTheme with textTheme (using for contrast).
colorScheme.onSecondary
Replace AppBarTheme.color with AppBarTheme.backgroundColor.
Material 3 Guidelines
Material 3 is the default theme as of Flutter 3.16.
Colors: Generate color schemes using ColorScheme.fromSeed(seedColor: Colors.blue). This ensures accessible contrast ratios.
Elevation: Material 3 uses ColorScheme.surfaceTint to indicate elevation instead of just drop shadows. To revert to M2 shadow behavior, set surfaceTint: Colors.transparent and define a shadowColor.
Typography: Material 3 updates font sizes, weights, and line heights. If text wrapping breaks legacy layouts, adjust letterSpacing on the specific TextStyle.
Modern Components:
Replace BottomNavigationBar with NavigationBar.
Replace Drawer with NavigationDrawer.
Replace ToggleButtons with SegmentedButton.
Use FilledButton for a high-emphasis button without the elevation of ElevatedButton.
Component Theme Normalization
Component themes in ThemeData have been normalized to use *ThemeData classes rather than *Theme widgets.
When defining ThemeData, strictly use the *ThemeData suffix for the following properties:
cardTheme: Use CardThemeData (Not CardTheme)
dialogTheme: Use DialogThemeData (Not DialogTheme)
tabBarTheme: Use TabBarThemeData (Not TabBarTheme)
appBarTheme: Use AppBarThemeData (Not AppBarTheme)
bottomAppBarTheme: Use BottomAppBarThemeData (Not BottomAppBarTheme)
inputDecorationTheme: Use InputDecorationThemeData (Not InputDecorationTheme)
Button Styling
Legacy button classes (FlatButton, RaisedButton, OutlineButton) are obsolete.
Use TextButton, ElevatedButton, and OutlinedButton.
Configure button appearance using a ButtonStyle object.
For simple overrides based on the theme's color scheme, use the static utility method: TextButton.styleFrom(foregroundColor: Colors.blue).
For state-dependent styling (hovered, focused, pressed, disabled), use MaterialStateProperty.resolveWith.
Platform Idioms & Adaptive Design
When building adaptive apps, respect platform-specific norms to reduce cognitive load and build user trust.
Scrollbars: Desktop users expect omnipresent scrollbars; mobile users expect them only during scrolling. Toggle thumbVisibility on the Scrollbar widget based on the platform.
Selectable Text: Web and desktop users expect text to be selectable. Wrap text in SelectableText or SelectableText.rich.
Horizontal Button Order: Windows places confirmation buttons on the left; macOS/Linux place them on the right. Use a Row with TextDirection.rtl for Windows and TextDirection.ltr for others.
Context Menus & Tooltips: Desktop users expect hover and right-click interactions. Implement Tooltip for hover states and use context menu packages for right-click actions.
Workflows
Workflow: Migrating Legacy Themes to Material 3
Use this workflow when updating an older Flutter codebase.
Task Progress:
1. Remove useMaterial3: false from ThemeData (it is true by default).
2. Replace manual ColorScheme definitions with ColorScheme.fromSeed().
3. Run validator -> review errors -> fix: Search for and replace deprecated accentColor, accentColorBrightness, accentIconTheme, and accentTextTheme.
4. Run validator -> review errors -> fix: Search for AppBarTheme(color: ...) and replace with backgroundColor.
5. Update ThemeData component properties to use *ThemeData classes (e.g., cardTheme: CardThemeData()).