Flutter Text Rendering
Render readable, predictable text across dynamic content lengths, locales, and accessibility settings.
Diagnose
Identify the failure mechanism before adjusting layout:
- Unconstrained flex overflow: An unconstrained
Text inside a Row or Flex expands infinitely, producing RenderFlex overflowed.
- Orphaned words (widows): The last word of a headline or paragraph dangles alone on a new line because line breaking occurred at the final whitespace.
- Uncontrolled truncation: Text clips silently or exceeds intended lines without a visible truncation affordance (
ellipsis, fade).
- Broken inline flow: Multiple adjacent
Text widgets in a Row break across lines awkwardly instead of flowing as a continuous paragraph.
- Text scale breakage: Enlarged system font scale (
TextScaler) causes text to clip inside fixed-height containers or push critical actions offscreen.
Rules
- Constrain text in flex layouts: Always wrap
Text in Expanded or Flexible when placed inside a Row, Column, or Flex where available space is bounded, and set overflow: TextOverflow.ellipsis with explicit maxLines.
- Prevent orphaned words: Use a non-breaking space (
\u00A0) between the final two words of headings, titles, and callouts so the last word never wraps alone to a new line.
- Choose deliberate truncation: Pair
maxLines with overflow: TextOverflow.ellipsis, TextOverflow.fade, or TextOverflow.clip. Do not set softWrap: false without verifying whether single-line clipping is acceptable.
- Use
Text.rich for inline styling: Prefer Text.rich (which inherits ambient DefaultTextStyle) over RichText (which requires explicit style and text direction) when mixing weights, colors, inline badges (WidgetSpan), or link recognizers.
- Measure text with
TextPainter when layout depends on copy size: When building dynamic chips, custom canvas callouts, or expandable "Read more" widgets, layout a TextPainter with explicit maxWidth and textScaler to check rendered height and didExceedMaxLines.
- Adapt to text scaling: Support enlarged system fonts (
MediaQuery.textScalerOf(context)). Avoid hardcoded container heights around text; prefer flexible or scrollable containers.
- Account for internationalization: Design copy containers to tolerate 20–35% text length expansion for localized strings and support bidirectional text (
TextDirection).
Conditional references
- Read text overflow and wrapping when fixing flex overflows, eliminating orphaned words with non-breaking spaces, configuring
TextPainter measurements, or managing multi-line truncation.
Verification
Exercise the text component with:
- Minimum length copy (empty or single short word).
- Realistic expected copy.
- Maximum length / localized copy (including accented and long non-whitespace strings).
- Enlarged font scaling (
TextScaler.linear(1.5) and TextScaler.linear(2.0)).
- Constrained parent widths (narrow mobile screens, tight cards, list items).
Write a widget test asserting no RenderFlex overflow, confirming intended line count, and verifying that truncation or non-breaking word pairing renders as expected.
Sources
1---2name: flutter-text-rendering3description: Diagnose and fix Flutter text display issues including text overflow, orphaned words, line breaking, truncation, multi-style spans, and text scaling. Use when text clips, leaves dangling single words, overflows containers, or requires rich inline spans; route typography tokens and visual hierarchy to flutter-ui-design and screen-level layout constraints to flutter-responsive-layout.4---56# Flutter Text Rendering78Render readable, predictable text across dynamic content lengths, locales, and accessibility settings.910## Diagnose1112Identify the failure mechanism before adjusting layout:13141. **Unconstrained flex overflow:** An unconstrained `Text` inside a `Row` or `Flex` expands infinitely, producing `RenderFlex overflowed`.152. **Orphaned words (widows):** The last word of a headline or paragraph dangles alone on a new line because line breaking occurred at the final whitespace.163. **Uncontrolled truncation:** Text clips silently or exceeds intended lines without a visible truncation affordance (`ellipsis`, `fade`).174. **Broken inline flow:** Multiple adjacent `Text` widgets in a `Row` break across lines awkwardly instead of flowing as a continuous paragraph.185. **Text scale breakage:** Enlarged system font scale (`TextScaler`) causes text to clip inside fixed-height containers or push critical actions offscreen.1920## Rules2122- **Constrain text in flex layouts:** Always wrap `Text` in `Expanded` or `Flexible` when placed inside a `Row`, `Column`, or `Flex` where available space is bounded, and set `overflow: TextOverflow.ellipsis` with explicit `maxLines`.23- **Prevent orphaned words:** Use a non-breaking space (`\u00A0`) between the final two words of headings, titles, and callouts so the last word never wraps alone to a new line.24- **Choose deliberate truncation:** Pair `maxLines` with `overflow: TextOverflow.ellipsis`, `TextOverflow.fade`, or `TextOverflow.clip`. Do not set `softWrap: false` without verifying whether single-line clipping is acceptable.25- **Use `Text.rich` for inline styling:** Prefer `Text.rich` (which inherits ambient `DefaultTextStyle`) over `RichText` (which requires explicit style and text direction) when mixing weights, colors, inline badges (`WidgetSpan`), or link recognizers.26- **Measure text with `TextPainter` when layout depends on copy size:** When building dynamic chips, custom canvas callouts, or expandable "Read more" widgets, layout a `TextPainter` with explicit `maxWidth` and `textScaler` to check rendered height and `didExceedMaxLines`.27- **Adapt to text scaling:** Support enlarged system fonts (`MediaQuery.textScalerOf(context)`). Avoid hardcoded container heights around text; prefer flexible or scrollable containers.28- **Account for internationalization:** Design copy containers to tolerate 20–35% text length expansion for localized strings and support bidirectional text (`TextDirection`).2930## Conditional references3132- Read [text overflow and wrapping](references/text-overflow-and-wrapping.md) when fixing flex overflows, eliminating orphaned words with non-breaking spaces, configuring `TextPainter` measurements, or managing multi-line truncation.3334## Verification3536Exercise the text component with:371. Minimum length copy (empty or single short word).382. Realistic expected copy.393. Maximum length / localized copy (including accented and long non-whitespace strings).404. Enlarged font scaling (`TextScaler.linear(1.5)` and `TextScaler.linear(2.0)`).415. Constrained parent widths (narrow mobile screens, tight cards, list items).4243Write a widget test asserting no `RenderFlex` overflow, confirming intended line count, and verifying that truncation or non-breaking word pairing renders as expected.4445## Sources4647- [Flutter Text class](https://api.flutter.dev/flutter/widgets/Text-class.html)48- [Flutter RichText class](https://api.flutter.dev/flutter/widgets/RichText-class.html)49- [Flutter TextPainter class](https://api.flutter.dev/flutter/painting/TextPainter-class.html)50- [Flutter TextOverflow enum](https://api.flutter.dev/flutter/rendering/TextOverflow.html)51- [Flutter TextScaler class](https://api.flutter.dev/flutter/painting/TextScaler-class.html)