Flutter now defaults to _not_ clip except for a few specialized widgets (such as `ClipRect`). To override the no-clip default, explicitly set `clipBehavior` in widgets constructions.
Original behavior
Flutter used to be slow because of clips. For example, the Flutter gallery app benchmark had an average frame rasterization time of about 35ms in May 2018, where the budget for smooth 60fps rendering is 16ms. By removing unnecessary clips and their related operations, we saw an almost 2x speedup from 35ms/frame to 17.5ms/frame.
New behavior
Not stated in the source.
- Who is affected
- Applications and packages relying on the previous behaviour or signature. Code that uses ClipRect, Card, Chip and related APIs.
- Practical impact
- Behaviour or API differences that can break builds or change runtime behaviour.
- What action should I take?
- Follow the official migration guide below, update affected call sites, run `dart fix --apply` where a fix is available, then run your tests.
Before and after (from the official guide)
| 1 | await tester.pumpWidget( | |
| 2 | Directionality( | |
| 3 | textDirection: TextDirection.ltr, | |
| 4 | child: Center( | |
| 5 | child: Stack( | |
| 6 | − | overflow: Overflow.visible, |
| 7 | children: const <Widget>[ | |
| 8 | SizedBox( | |
| 9 | − | width: 100, |
| 10 | − | height: 100, |
| 11 | ), | |
| 12 | ], | |
| 13 | ), | |
| 14 | ), | |
| 15 | ), | |
| 16 | ); |
| 1 | await tester.pumpWidget( | |
| 2 | Directionality( | |
| 3 | textDirection: TextDirection.ltr, | |
| 4 | child: Center( | |
| 5 | child: Stack( | |
| 6 | + | clipBehavior: Clip.none, |
| 7 | children: const <Widget>[ | |
| 8 | SizedBox( | |
| 9 | + | width: 100.0, |
| 10 | + | height: 100.0, |
| 11 | ), | |
| 12 | ], | |
| 13 | ), | |
| 14 | ), | |
| 15 | ), | |
| 16 | ); |
Raw before / after
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: Stack(
overflow: Overflow.visible,
children: const <Widget>[
SizedBox(
width: 100,
height: 100,
),
],
),
),
),
);await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: Stack(
clipBehavior: Clip.none,
children: const <Widget>[
SizedBox(
width: 100.0,
height: 100.0,
),
],
),
),
),
);Official migration guide (excerpt, © The Flutter Authors, CC BY 3.0)
You have 4 choices for migrating your code:
- Leave your code as is if your content does not need to be clipped (for example, none of the widgets' children expand outside their parent's boundary). This will likely have a positive impact on your app's overall performance.
- Add
clipBehavior: Clip.hardEdgeif you need clipping, and clipping without anti-alias is good enough for your (and your clients') eyes. This is the common case when you clip rectangles or shapes with very small curved areas (such as the corners of rounded rectangles). - Add
clipBehavior: Clip.antiAliasif you need anti-aliased clipping. This gives you smoother edges at a slightly higher cost. This is the common case when dealing with circles and arcs. - Add
clip.antiAliasWithSaveLayerif you want the exact same behavior as before (May 2018). Be aware that it's very costly in performance. This is likely to be only rarely needed. One case where you might need this is if you have an image overlaid on a very different background color. In these cases, consider whether you can avoid overlapping multiple colors in one spot (for example, by having the background color only present where the image is absent).
For the Stack widget specifically, if you previously used
overflow: Overflow.visible, replace it with clipBehavior: Clip.none.
For the ListWheelViewport widget, if you previously specified
clipToSize, replace it with the corresponding clipBehavior:
Clip.none for clipToSize = false and
Clip.hardEdge for clipToSize = true.
Code before migration:
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: Stack(
overflow: Overflow.visible,
children: const <Widget>[
SizedBox(
width: 100,
height: 100,
),
],
),
),
),
);Code after migration:
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: Stack(
clipBehavior: Clip.none,
children: const <Widget>[
SizedBox(
width: 100.0,
height: 100.0,
),
],
),
),
),
);AI_PROVIDER (for example to openai-compatible with a local Ollama or LM Studio endpoint) to enable grounded explanations. Everything else on this page works without an AI provider.Listed in the official breaking-changes index (docs.flutter.dev/release/breaking-changes).
An official announcement or migration guide documents an intended behaviour or API change. A verified source change (git diff) shows code changed but does not by itself prove a public API is breaking. AI interpretations are labelled and never used to classify a change.
- Official migration guide
- Clip
- Issue 13736
- Issue 18057
- Issue 21830
- PR 5420
- PR 18576
- PR 18616
- PR 5647
- PR 5670
- PR 5853
- PR 5868
- PR 5973
- PR 5952
- PR 20205
- PR 20538
- PR 20751
- PR 20752
- PR 21012
- PR 21703
- PR 21826
- Source commit
- b3045439b7c0
- Source last updated
- Oct 21, 2026
- Last synchronized
- Oct 21, 2026
- Publication status
- published
Publication history
- Oct 21, 2026, 8:31 PM: new → published (ingestion) — Backed by an official breaking-change/migration guide.
AI_PROVIDER (for example to openai-compatible with a local Ollama or LM Studio endpoint) to enable grounded explanations. Everything else on this page works without an AI provider.