overflow_guard
Catch RenderFlex overflow across many device sizes automatically — in your widget tests / CI, or live at runtime.
device_preview lets you look at your app on other devices by hand.
overflow_guard checks for you and fails the test when a screen
overflows on any size — so a "breaks on small phones" bug is caught before you
ship it, not after a user hits it.
Install
Add it to your dev_dependencies (it is only needed for tests):
dev_dependencies:
overflow_guard: ^0.2.1
Then run flutter pub get.
Test your screens in 3 steps
1. Create a test file — test/layout_test.dart:
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:overflow_guard/testing.dart';
import 'package:your_app/checkout_screen.dart';
void main() {
testWidgets('Checkout fits every device size', (tester) async {
final report = await checkLayout(
tester,
const CheckoutScreen(),
devices: DeviceSize.all, // small phone -> large tablet
);
expectNoOverflow(report); // fails with an exact per-device report
});
}
2. Run it:
flutter test
3. Read the result. If a screen overflows you get an exact table:
LayoutReport: 2 of 7 device sizes overflowed.
[PASS] Standard phone (390x844)
[FAIL] Small phone (320x568): 24.0px on the right
[FAIL] Foldable (narrow) (280x653): 64.0px on the right
...
Now you know the screen, the device size, the edge, and the exact pixels — before shipping.
Choosing device sizes
DeviceSize.common // 5 everyday sizes: small -> large phone + a tablet
DeviceSize.all // 7 sizes incl. narrow foldable + large tablet (strictest)
// Or your own:
await checkLayout(tester, const HomeScreen(), devices: const [
DeviceSize.smallPhone,
DeviceSize('Company kiosk', 1080, 1920, pixelRatio: 1),
]);
Catch more: large fonts and async screens
Two common overflow causes a default check misses:
await checkLayout(
tester,
const ProfileScreen(),
devices: DeviceSize.all,
textScales: const [1.0, 1.3, 2.0], // large-font accessibility users
settle: true, // wait for async/loading content
);
textScales re-runs each device at those font scales (a top real-world cause
of overflow). settle calls pumpAndSettle so a screen that loads data renders
its real content before the check instead of a spinner.
Runtime detection (optional)
You can also watch for overflow live while the app runs:
import 'package:overflow_guard/overflow_guard.dart';
final recorder = OverflowRecorder()..start();
// ... render UI ...
if (recorder.hasOverflow) {
debugPrint(recorder.issues.toString()); // e.g. [24.0px on the right]
}
How it works
Flutter reports overflow through FlutterError.onError. OverflowRecorder
temporarily intercepts that handler, keeps overflow messages, and forwards all
other errors untouched. checkLayout drives the widget test's fake screen to
each DeviceSize (with a fresh render tree per size, so nothing is
de-duplicated) and records what overflows.
API at a glance
| Symbol | Import | Use |
|---|---|---|
checkLayout(tester, screen, {devices}) |
testing.dart |
Run the multi-device check in a widget test |
expectNoOverflow(report) |
testing.dart |
Fail the test if anything overflowed |
LayoutReport |
either | hasOverflow, failures, describe() |
DeviceSize |
either | Size presets + custom sizes |
OverflowRecorder |
overflow_guard.dart |
Live runtime detection |
Libraries
- overflow_guard
- overflow_guard -- runtime library.
- testing
- overflow_guard -- test-time library.