Saturday, May 13, 2017

React Native Text and Flex 0

Flex is a core tool in React Native's Layout system. Flex is used to define how much space a view should take relative to it's siblings. There are 3 types of values for it: negative, positive and 0. When used with Views, or most of the components provided by React Native, flex's behavior closely matches that described in its docs. However when flex is used on Text it can seem slightly differenc.

To reproduce the scenarios covered in this article you can play with the code on

The React Native docs do a great job describing the behavior of flex, so let's use that as our starting point:
When flex is a positive number, it makes the component flexible and it will be sized proportional to its flex value. So a component with flex set to 2 will take twice the space as a component with flex set to 1.
When flex is 0, the component is sized according to width and height and it is inflexible.
When flex is -1, the component is normally sized according width and height. However, if there's not enough space, the component will shrink to its minWidth and minHeight.
However, if you start applying flex to side by side Text components, you may begin to notice a difference behavior as the amount of text in the view changes. If you have a lot of text in two side by side text views, each with flex 0, they will not wrap until after they are overflowing off the side of the screen. While this is a very specific annoyance, it can crop up when trying to place Text next to any element (an icon for example).

Flex of 0 with short text, looking good!
flex of 0 with long text, the icon is cropped
This is because Text does not have the same concept of "intrinsic size" that other components have. As you add more text to a Text component its intrinsic size will increase until it reaches the width of its parent container. As a result, if you try putting two Text components with a lot of text and a flex of 0 side by side, they will not honor the dimensions of their parent. Instead, they will begin to wrap when each of their widths reaches the width of the parent container.

The fix to prevent this overflow is to use a flex of -1. This will allow the text to use as much width as is available to them while shrinking their width if their combined width exceeds their parent's boundariesIt is also worth noting that positive flex will still distribute the available width based on the flex applied to each component.
Flex of -1 with short text, same behavior

Flex of -1 with long text, no more cropping

Flex of 1 with short text for reference
As simple as this may be, I hope it saves someone else some pain and time. Please comment with any questions or feedback you have!


Post a Comment