overflow_guard 0.2.1
overflow_guard: ^0.2.1 copied to clipboard
Catch RenderFlex overflow across many device sizes and text scales at once, in widget tests / CI or live at runtime. Reports exactly where each screen overflows.
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 |