Focus outline for interactive widgets
Draw a consistent, animated focus outline around any interactive widget.
Providing a uniform focus indication can be surprisingly hard in real apps:
default focus highlights can be clipped by layout, covered by other widgets, or
look inconsistent across components. This package draws the focus outline in an
Overlay, helping you keep a consistent design and improve UX while working
toward accessibility guidelines (e.g. WCAG/BITV) that require visible keyboard
focus.
Features
- Draws a focus outline for a widget when it (or a descendant) is focused
- Works across different focusable widgets (buttons, fields, custom widgets)
- Multiple stroke styles: solid, dashed, dotted
- Optional bordered stroke (inner color + outer border color)
- Built-in animations, including configurable stroke reveal
- Implemented via
Overlay+CompositedTransformFollowerto avoid clipping
Getting started
Add the dependency:
dependencies:
focus_outline: ^0.1.0
Minimum supported Flutter SDK is >=3.10.0 (see pubspec.yaml).
Usage
Wrap any focusable widget:
import 'package:flutter/material.dart';
import 'package:focus_outline/focus_outline.dart';
class Example extends StatelessWidget {
const Example({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: FocusOutline(
strokeWidth: 3,
child: OutlinedButton(
onPressed: () {},
child: const Text('Focusable'),
),
),
);
}
}
Stroke styles
FocusOutline(
strokePattern: FocusOutlineStrokePattern.dashed,
dashLength: 14,
dashGap: 10,
child: const TextField(),
);
FocusOutline(
strokePattern: FocusOutlineStrokePattern.dotted,
strokeCap: StrokeCap.round,
dashGap: 10,
child: const TextField(),
);
Bordered outline (stroke + border)
FocusOutline(
color: Colors.blue,
strokeWidth: 3,
strokeBorderColor: Colors.black,
strokeBorderWidth: 2,
child: const TextField(),
);
Animations
By default, FocusOutline uses FocusOutlineAnimation.none (no animation).
FocusOutline(
duration: const Duration(milliseconds: 300),
animationBuilder: FocusOutlineAnimation.fadeScale,
child: const TextField(),
);
Stroke reveal
FocusOutline(
duration: const Duration(milliseconds: 300),
animationBuilder: FocusOutlineAnimation.strokeReveal(
start: FocusOutlineStrokeStart.topCenter,
type: FocusOutlineStrokeType.bidirectional,
),
child: const TextField(),
);
Accessibility notes
Ensure the outline color has sufficient contrast against the background.
Contributing
Contributions are welcome. Please open an issue or a pull request.
License
MIT. See LICENSE.
Libraries
- focus_outline
- A Flutter widget that draws a consistent, animated focus outline.
- testing
- Test-only utilities for
focus_outline.