Skip to main content

Flexbox Troubleshooting

A few issues may be encountered while using flexbox. This section discusses the more common of those issues, which may prove useful when debugging and finding issues in layout.

For debugging, the Flipper layout inspector plugin can be used to see the component hierarchy, and the flex properties can be updated in the plugin itself to understand how it affects layout.

Another tool that can be used for understanding and playing around with flexbox properties is Yoga Playground.

Why is my text truncated?​

One common problem is that there is not enough space for content to be visible on the screen and therefore text gets truncated. The default value of flexShrink is 1.0f. So, if there is not enough space available for the text to render completely then text will shrink and and will be shown truncated on the screen. Changing the flexShrink value to 0 makes sure that text component is not shrinked.

Imagine there are two Text components in a Row. If no flex properties are defined on either of the Text components, then they both will take equal space and text will be truncated if text is too long to fit into available space. Now, if flexShrink = 0f is added to the first Text, then it won't shrink and take up the whole space to render itself completely; the second Text will take up the remaining space.

override fun ComponentScope.render(): Component {
return Row(style = Style.padding(16.dp)) {
child(
Text(
style =
Style.flex(shrink = 0f), // If flexShrink is 1f then this text will be truncated
text = "This is a really long text.",
textSize = 20.sp,
maxLines = 1))
child(
Text(
style = Style.margin(start = 8.dp),
text = "Another long text",
textSize = 20.sp,
maxLines = 1))
}
}

However, if the second Text is still truncated, based on the requirements, then either make it multiline or display the two Texts inside a Column.

Another scenario where text can get truncated is if there is an exact width and height defined on a sibling component, which is taking up all the available space and not allowing other children to grow. In this case, either remove the exact width/height defined so that both siblings can grow and take up the available space or set flexShrink to 0 on sibling component.

override fun ComponentScope.render(): Component {
return Column(style = Style.height(135.dp).padding(16.dp)) {
child(
Column(style = Style.heightPercent(100f).widthPercent(100f)) {
// either remove widthPercent / heightPercent here so that both siblings can grow
// equally
child(Text(text = "This is a really long text.", textSize = 20.sp, maxLines = 1))
child(
Text(
style = Style.margin(top = 8.dp),
text = "Subtitle text",
textSize = 20.sp,
maxLines = 1))
})
child(
Text(
// or add flex(shrink = 0f) so that this component does not shrink
style = Style.margin(top = 16.dp),
text = "Small footer text",
textSize = 20.sp,
maxLines = 1))
}
}

How to build overlapping components?​

This can be achieved by using position type as YogaPositionType.ABSOLUTE. Also, the exact left/right coordinates for the starting position of the absolute child can be set. For information on making components overlap each other, see Absolutely positioned items.

How to center components?​

Use the following to center components:

If it is specific to Text, then consider using verticalGravity/horizontalGravity props of the Text component to keep it center-aligned:

  Text(
text = "Align this text at center vertically using vertical gravity",
verticalGravity = VerticalGravity.CENTER,
textSize = 20.sp))

If flexGrow/flexShrink has been defined but doesn't do anything​

If the parent has fixed width/height then flexGrow/flexShrink is not expected to work correctly since there is not enough space for it to work with. Check in the component hierarchy if the component that is getting clipped has enough width/height needed to render it completely.

override fun ComponentScope.render(): Component {
return Column(style = Style.height(50.dp).padding(16.dp)) { // exact height defined here
child(
Text(
style =
Style.flex(
shrink =
0f), // Even with flexShrink zero, text will be cut as there is not enough
// space
text = "This is a really long text.",
textSize = 20.sp,
maxLines = 1))
child(
Text(
style = Style.margin(start = 8.dp),
text = "Another long text",
textSize = 20.sp,
maxLines = 1))
}
}

When the keyboard opens, the content is cut off​

When there is a screen for which input is required (such as when the layout contains a TextInput), then the layout now needs to fit inside a small space (here, height is the concern).

There are multiple ways to solve this:

  1. Check if the text is cut off due to flexShrink issues or check the setting for exact width/height on parent components in the hierarchy.

  2. Make the content scrollable by placing it in a VerticalScroll.

    override fun ComponentScope.render(): Component {
    return VerticalScroll {
    Column {
    for (i in 0..20) {
    child(
    Text(
    style = Style.padding(16.dp).margin(top = 8.dp),
    text = "Text counter = " + i,
    textSize = 20.sp,
    maxLines = 1))
    }
    }
    }
    }
  3. Keep a state value that tracks whether the keyboard is open or not, then change the layout accordingly, depending on the state.