fluttersmith/tipsGitHub ↗

Style an ElevatedButton with styleFrom and themes

BeginnerWidgets & layout2 min read#buttons#theming✓ Verified · Flutter 3.47.5 · 27 Sept 2026

ElevatedButton takes a ButtonStyle, and building one by hand is verbose. ElevatedButton.styleFrom takes plain values and does it for you:

buttons.dart✓ analyzed · tested
return ElevatedButton(
  style: ElevatedButton.styleFrom(
    foregroundColor: Colors.white,
    backgroundColor: Colors.indigo,
    disabledBackgroundColor: Colors.grey.shade300,
    shape: const StadiumBorder(),
    padding: const EdgeInsets.symmetric(horizontal: 32),
  ),
  onPressed: onPressed,
  child: const Text('Checkout'),
);
  1. plain values in, a full ButtonStyle out

styleFrom fills in the states for you, too: disabledBackgroundColor is used when onPressed is null, and the pressed and hover overlays are derived from foregroundColor.

Style every button at once

Copying that style onto each button doesn’t scale. Put it in the theme:

buttons.dart✓ analyzed · tested
return MaterialApp(
  theme: ThemeData(
    elevatedButtonTheme: ElevatedButtonThemeData(
      style: ElevatedButton.styleFrom(
        foregroundColor: Colors.black,
        backgroundColor: Colors.amber,
      ),
    ),
  ),
  home: home,
);
  1. applies to buttons without their own style

Every ElevatedButton without its own style now picks it up. A local style still wins, property by property: a button that only sets backgroundColor keeps the theme’s foregroundColor.

Styles that depend on state

When one property should differ per state, build a ButtonStyle with WidgetStateProperty:

buttons.dart✓ analyzed · tested
final pressableStyle = ButtonStyle(
  backgroundColor: WidgetStateProperty.resolveWith((states) {
    if (states.contains(WidgetState.disabled)) return Colors.grey;
    if (states.contains(WidgetState.pressed)) return Colors.indigo;
    return Colors.indigo.shade300;
  }),
  foregroundColor: const WidgetStatePropertyAll(Colors.white),
);
  1. called with the current states on every change

resolveWith gets the current set of WidgetStates: pressed, hovered, focused, disabled and so on. Check the most specific ones first. For a value that never changes, WidgetStatePropertyAll saves you the function.

The test for this tip presses the button and checks that the painted color changes, then disables it and checks again.

Migrating older code

MaterialStateProperty and MaterialState are the old names. They’re deprecated aliases of WidgetStateProperty and WidgetState, so a find and replace is all it takes. Older still, RaisedButton and its color parameter are gone; ElevatedButton with styleFrom is the replacement.

Adapted from tip #11 in Flutter Tips & Tricks by Andrea Bizzotto (MIT). Updated for current Flutter. Not affiliated with or endorsed by the original author. Suggest an edit.