Skip to content

Text Directionality

Supporting variable text directions is a critical component of internationalization. While many languages such as English are read left-to-right (LTR), a great number including Arabic, Hebrew, and Farsi are read right-to-left (RTL). Text directionality impacts not only how text itself is displayed, but the layout and design of your app as a whole.

Fortunately, Flutter provides robust capabilities for handling variable text directions. Utilizing these correctly will allow your application to make visual sense to all users.

Let’s explore how Flutter handles text directionality and discuss important guidelines for ensuring your app supports both LTR and RTL text flawlessly.

How Flutter Handles Text Directionality

The Directionality widget is the basis of direction handling in Flutter. Its textDirection property controls how direction is assigned and can have a value of TextDirection.ltr or TextDirection.rtl, which will be furnished as a default text direction to all of the widget’s children.

A default global Directionality exists across the widget layer in Flutter and is determined by the user’s locale. See the Internationalizing Flutter Apps documentation for more information on locales in Flutter.

Directionality can also be explicitly supplied to widgets through use of the Directionality widget as a parent.

Let’s observe how directionality impacts the display of various elements in a flutter app. Here we have a Directionality widget which furnishes a variable text direction to a row and its children:

Directionality(
textDirection: textDirectionLTR ? TextDirection.ltr : TextDirection.rtl,
child: Row(
children: [
// children
],
),
),
Table comparing directional variants of one text widget, two text widgets, and two container widgets.

As you can see in the first ‘hello world’ example, the text becomes right-aligned once textDirection is RTL, but the string remains displayed as typed. RTL strings are entered right-to-left and thus are handled the same way.

Note that in the second, ‘hello’, ‘world’, example that the order of elements will be flipped for ordered, direction-sensitive widgets such as this Row. This applies to non-text elements as well, as illustrated by the third example displaying colored boxes in a row.

Tips for Handling Directionality in Flutter Like a Pro

Know when to use visual versus directional widgets.

The mirroring behavior exhibited by text-direction-sensitive widgets presents a unique challenge for developers. For example, how are text-aligned elements supposed to maintain their relative position when the alignment of the text itself is being flipped? What about widgets that require an absolute position independent of any text direction changes?

Flutter has introduced a powerful system for expressing the precise behavior you want for many direction-sensitive widgets, but it’s important to understand its details in order to get the most out of your bidirectional app.

Flutter offers both visually- and directionally-demarcated versions of many relevant widgets and values. Visually-based values are defined in absolute directions such as top, left, right, and bottom. Directionally-based widgets, by contrast, are defined in terms relative to the widget’s directional alignment: top, start, end, and bottom.

This distinction is illustrated by comparing the EdgeInsets and EdgeInsetsDirectional classes. If we want to introduce a padding value that always comes before the beginning of a text widget, EdgeInsetsDirectional allows us to maintain that relative position regardless of the text’s orientation:

Padding(
padding: EdgeInsetsDirectional.only(start: 12),
child: Text('Whether RTL or LTR, padding will always be at the start of this string!'),
),
Padding(
padding: EdgeInsets.only(left: 10),
child: Text('Padding will always be to the left of this string!'),
)

Many Flutter widgets, including Positioned and Border, have Directional variants that will allow you to specify the exact relationship you want them to have with directionality.

Account for non-text elements.

Text isn’t the only content in your app that changes with directionality! Many Flutter icons will also by default be mirrored when the text direction flips:

Left-to-right and right-to-left variants of a bicycle icon.

Icons.directions_bike in LTR and RTL alignments (source: material.io)

Images may need to be flipped as well. Image and most other default graphics widgets have a matchTextDirection property which is false by default. When set to true, the image will be drawn starting from the top left (default behavior) in LTR environments, and from the top right in RTL environments, mirroring the image.

Follow bidirectional mirroring standards.

There are established guidelines for which elements should and should not be mirrored when switching between LTR and RTL layouts. For example, visual references to a forward direction or future time (e.g. an arrow pointing right in an LTR layout) should be mirrored, whereas media progress indicators should remain oriented LTR as they model the direction of a tape being played.

There are similar conventions in place for negation symbols, physical objects, and other potentially bidirectional components. Adhering to these standards is essential for a clear and globally comprehensible user interface. For an overview of bidirectional design conventions, read Material Design’s Bidirectionality guide.