How to Set the Width and Height of a Flutter Button: Complete Guide to ButtonStyle
Use ElevatedButton.styleFrom() (or the equivalent factory on TextButton, OutlinedButton, or FilledButton) and pass a Size object to the minimumSize parameter for flexible dimensions or fixedSize for exact dimensions.
Every Material button in the Flutter framework derives its visual dimensions from a ButtonStyle object. According to the flutter/flutter repository source code, controlling the width and height requires understanding two distinct properties—minimumSize and fixedSize—which are configured through the button’s styleFrom factory constructor.
Understanding Button Sizing Properties
Flutter’s button implementations (ElevatedButton, TextButton, OutlinedButton, FilledButton) delegate their layout constraints to the ButtonStyle class defined in packages/flutter/lib/src/material/button_style.dart. When you need to set the width and height of a Flutter button, you manipulate two specific properties:
minimumSize: Specifies the smallest allowable dimensions. The button expands to fit its child content but will never collapse below this size.fixedSize: Enforces exact dimensions regardless of the child widget’s size.
Internally, the styleFrom factory in packages/flutter/lib/src/material/elevated_button.dart (lines 188-204) forwards these values to ButtonStyleButton.allOrNull<Size?>, which creates a WidgetStateProperty that the rendering layer consumes during layout.
Setting Minimum Size vs Fixed Size
Using minimumSize for Flexible Dimensions
The minimumSize property is ideal when you want to enforce baseline dimensions while allowing the button to grow if the child requires more space. In packages/flutter/lib/src/material/elevated_button.dart, the styleFrom method processes this parameter via ButtonStyleButton.allOrNull<Size>.
ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: const Size(200, 60), // Minimum 200px wide, 60px tall
),
onPressed: () {},
child: const Text('Minimum 200×60'),
);
The button will respect these dimensions as lower bounds but can expand horizontally or vertically if the text or icon child demands additional space.
Using fixedSize for Exact Dimensions
When you need a button to maintain precise dimensions—such as a square icon button—use fixedSize. This property creates tight constraints that override natural sizing behavior.
OutlinedButton(
style: OutlinedButton.styleFrom(
fixedSize: const Size(120, 120), // Forces exact 120px square
),
onPressed: () {},
child: const Icon(Icons.star),
);
As implemented in packages/flutter/lib/src/material/button_style_button.dart (lines 124-127), fixedSize is handled identically to minimumSize through the allOrNull utility, but the layout delegate applies these values as rigid constraints to the underlying RenderConstrainedBox.
Alternative Approaches to Button Sizing
Wrapping with SizedBox
You can bypass ButtonStyle entirely by wrapping the button in a SizedBox, which supplies tight constraints that the button must respect regardless of its internal style configuration.
SizedBox(
width: 250,
height: 48,
child: TextButton(
onPressed: () {},
child: const Text('Wrapped in SizedBox'),
),
);
Combining Padding with Size Constraints
The padding property works orthogonally to size constraints. When combined with minimumSize, padding is added inside the constrained dimensions, increasing the visual button size while maintaining the structural minimums.
ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: const Size(180, 48),
padding: const EdgeInsets.symmetric(horizontal: 24),
),
onPressed: () {},
child: const Text('Padded Minimum Size'),
);
Applying Size Constraints Globally via Theme
For design consistency across your application, set default dimensions in the ThemeData. The elevatedButtonTheme property accepts an ElevatedButtonThemeData that applies to all ElevatedButton instances in the widget tree.
MaterialApp(
theme: ThemeData(
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
minimumSize: const Size(150, 50),
),
),
),
home: const Scaffold(
body: Center(
child: ElevatedButton(
onPressed: null,
child: Text('Theme-wide size'),
),
),
),
);
This approach leverages packages/flutter/lib/src/material/elevated_button_theme.dart to inject the ButtonStyle into every descendant button.
How Button Sizing Works Under the Hood
The architectural flow for button sizing follows a clear path through the Flutter framework:
- User configuration: You call
ElevatedButton.styleFrom(minimumSize: Size(...))in your widget tree. - Style construction: The factory builds a
ButtonStyleobject usingButtonStyleButton.allOrNull<Size>to wrap the rawSizevalue in aWidgetStateProperty. - State management: In
_ButtonStyleState(located inpackages/flutter/lib/src/material/button_style_button.dart), the widget reads the resolvedminimumSizeorfixedSizevalues. - Layout enforcement: These values are passed to the rendering layer as constraints to a
RenderConstrainedBox, which enforces the final dimensions during the layout phase.
The ButtonStyle class declaration in packages/flutter/lib/src/material/button_style.dart (lines 73-76) defines these properties as WidgetStateProperty<Size?>, allowing them to respond to interaction states (hovered, pressed, disabled) if needed.
Summary
- Use
minimumSizeto set baseline dimensions while permitting the button to expand for larger content. - Use
fixedSizeto force exact width and height regardless of child size. - Both properties are configured via the
styleFromfactory on any Material button type. - Internally,
ButtonStyleButton.allOrNullconverts rawSizevalues intoWidgetStatePropertyobjects that the layout system enforces throughRenderConstrainedBox. - For global changes, apply size constraints through
ThemeDatarather than individual button styles.
Frequently Asked Questions
What is the difference between minimumSize and fixedSize in Flutter buttons?
minimumSize establishes lower bounds for dimensions—the button can grow larger but never smaller than the specified size. fixedSize creates rigid constraints that force the button to maintain exact dimensions, potentially clipping child content that exceeds those bounds. Both are properties of ButtonStyle and are typically set through the styleFrom factory method.
Can I set only the width or only the height of a Flutter button?
Yes. Pass double.infinity for the dimension you want to remain flexible. For example, Size(200, double.infinity) constrains only the width while allowing the height to adjust based on content and padding. However, when using fixedSize, you must specify concrete values for both axes.
Why does my button ignore the size constraints I set?
Ensure you are setting the style properties on the correct button type and not overriding them with a parent SizedBox or Container with different constraints. Additionally, verify that you are not passing null to styleFrom—the parameter expects a concrete Size object. If using themes, check that no descendant ButtonStyle is overriding your theme configuration with style: null.
How do I make all buttons in my app the same size?
Define the size constraints in ThemeData using the appropriate theme property (e.g., elevatedButtonTheme, textButtonTheme). Set the minimumSize or fixedSize in the theme’s style to apply consistent dimensions across all instances of that button type without manually configuring each widget.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →