bevyengine / bevyengine/bevy

`max_width/height` constraints don't compose correctly with measure funcs

Open
#15,543 4 comments 0 reactions 0 assignees View on GitHub
A-UI C-Bug D-Straightforward S-Needs-Investigation
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

## Bevy version

main

## What went wrong

`text_debug` example:
text_debug

The yellow and green text nodes are missing their last lines.

## Investigation

This seemed like a problem with the text measure func returning an incorrect height but I went through the code and couldn't find any problems. It seems like it emits the correct values.

I changed the example so that the the text is wrapped in a default UI node like this:

```rust
builder.spawn(NodeBundle::default())
.with_child(
TextBundle::from_section(
"This text is left-justified and is vertically positioned to distribute the empty space equally above and below it.",
TextStyle {
font: font.clone(),
font_size: 29.0,
color: YELLOW.into(),
},
)
.with_background_color(MAROON.into())
.with_text_justify(JustifyText::Left)
.with_style(Style {
max_width: Val::Px(300.),
..default()
}),
);
```

Which should have no affect on the layout but instead we see the entire text node is now rendered, but its position has been moved to the left edge, half way out of the window:

![Image](https://github.com/user-attachments/assets/145d2fe0-e44e-4907-971d-dca580efe687)

If we move the `max_width` constraint to the wrapping parent:

```rust
builder.spawn(NodeBundle {
style: Style { max_width: Val::Px(300.), ..default() },
..default()
})
.with_child(
TextBundle::from_section(
"This text is left-justified and is vertically positioned to distribute the empty space equally above and below it.",
TextStyle {
font: font.clone(),
font_size: 29.0,
color: YELLOW.into(),
},
)
.with_background_color(MAROON.into())
.with_text_justify(JustifyText::Left)
);
```

then everything is correct, the text is rendered at the correct position in its entirety.

Also if you remove the local constraints entirely but keeping the parent node:

```rust
builder.spawn(NodeBundle {
..default()
})
.with_child(
TextBundle::from_section(
"This text is left-justified and is vertically positioned to distribute the empty space equally above and below it.",
TextStyle {
font: font.clone(),
font_size: 29.0,
color: YELLOW.into(),
},
)
.with_background_color(MAROON.into())
.with_text_justify(JustifyText::Left)
);
```

and then apply the `max_width: 300.` constraint to the grandparent right column UI node, the text ignores that `max_width` constraint and is just rendered as a single line:

![Image](https://github.com/user-attachments/assets/13fff227-ce87-4f44-a8c4-0121da2ae539)

There seem to be similar problems with `max_height` too, I didn't test these too much though.

#

This seems to be a bug in Taffy.
The behaviours changed slightly with each Taffy version update and the position of a node in the layout is determined entirely by taffy. If there was a bug in our measure func code it should only be able to affect a nodes size and not its position,

I tried to go back farther to when we were using Taffy 3.x but the examples from then wouldn't run on my computer.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.