Auto height issues in TextBlock with padding and other controls; possible bug

TL;DR

What is the best method to build a UI that requires TextBlocks and padding without having to manually calculate each Control’s height?

Are these bugs or expected behavior?

  • Children of a StackPanel with padding get clipped unexpectedly.
  • adaptHeightToChildren doesn’t seem to calculate properly when StackPanel is involved.
  • adaptHeightToChildren doesn’t maintain bottom padding as expected.

Playground with Tests


Full Detail

What is the best method to have a TextBlock automatically set it’s height based on the amount of text AND have some sort of padding around the TextBlock?

Below are notes I took while trying to build a layout. Each test noted below can be found in the Playground Example. Uncomment the test you want to run at the end of the file.

1

My base control will be a Rectangle with a fixed width, 100% height, a background color, and 16px of padding. This is the Panel in which my controls will be added. I will refer to this as the Surface Panel.

Test 1:

2

A TextBlock can size itself using .resizeToFit = true combined with .textWrapping = WordWrap. In my scenario, I can assume that the width of the TextBox will be 100%, determined by some parent container (likely a Rectangle, Container, or StackPanel). Any padding added to the TextBlock will function as expected, reducing the usable width of the TextBlock. All is good so far.
Test 2:

3

Now, I want to place the TextBlock in a Rectangle to create a ‘card’ style. I can create a Rectangle with 100% width and use .adaptHeightToChildren = true to have the Rectangle become the same height as the TextBlock. Without this, the Rectangle would be 100% height which is not desired or the height would need to be manually calculated.
Test 3:

4

Next, I want to add a second card to the layout. I can create a StackPanel and then add two cards as children. Everything still seems good. I’ve got two cards, each with text inside surrounded by padding. The two cards are stacked vertically. Somehow the StackPanel is only the size of its children - is this its default handling?
Test 4:

5

Lastly, I want to add padding between the cards (or StackPanel) and the Surface Panel. I can do this by adding padding to the StackPanel. This is where I start to run into problems.
Test 5:


I get that nice padding around the StackPanel I wanted, but it breaks the layout of the children cards. Is this behavior expected?

Problem 1: Children of a StackPanel with padding get clipped unexpectedly.

6

Ok, I’ll scrap the padding on the StackPanel to get back to a clean design. The surface panel is using padding, and that isn’t breaking the layout at all. Let’s try adjusting that padding and see how the cards react.

Test 6:


Removing the padding of the Surface Panel doesn’t cause any harm.

7

Increasing the padding also works as expected. The children are sized as expected and are not clipped.
Test 7:

8

Alright, since Test 6 & 7 didn’t cause any problems, lets see if adding another Rectangle between the surface and StackPanel would work. I will call this Rectangle the Padding Panel.
Test 8:


Looks like it worked! I seem to have found a layout that will be responsive while setting the width on a single control.

9

This is nearly a complete layout for my design, however there is an important piece missing. I don’t want the Surface Panel to be full height. I want it to expand and shrink to fit its content. It looks like I can do this with .adaptHeightToChildren = true on the two panels that need to shrink: Surface Panel and the Padding Panel.

Unfortunately I am running into a clipping problem again.

Test 9:

Problem 2: adaptHeightToChildren doesn’t seem to calculate properly when StackPanel is used.

10

I can showcase this problem differently by only applying the adaptHeightToChildren property to the direct parent of the StackPanel.

We can see that the issue definitely occurs here. Notice that we have lost the bottom green corners of the StackPanel. This leads me to believe that there is a calculation issue with the StackPanel.

Test 10:

11

I tried setting adaptHeightToChildren on the StackPanel as well. With similar, but worse results.

Test 11:


Could this signify there may be a problem with the calculated height of the Content Cards?

12

I should note that if I give the StackPanel an explicit height in pixels, it’s parent Rectangles adapt to the size, but not perfectly.

The content obviously fits, but that nice looking padding between the StackPanel and Surface I accomplished in Test 8 is now broken. There is no bottom padding anymore. Notice the StackPanel’s green background goes all the way to the bottom of the UI.

Test 12:

Problem 3: adaptHeightToChildren doesn’t maintain bottom padding as expected.

Questions:

  • Any suggested solutions or improvements?
  • Does BabylonJS GUI follow any specific box-model similar to the CSS models?
  • Is padding included or excluded in height/width properties?
  • How does a StackPanel determine its height if it is not explicitly set?
  • Is it possible to inline styles in a TextBlock? Ie. bold specific words in the TextBlock?
2 Likes

I am sorry to be so n00b with Gui, I ll add @Evgeni_Popov to the thread as he might have some good insights :slight_smile:

Going to have a look.

1 Like

This PR should fix almost all the problems:

The remaining problem is when using adaptWidthToChildren / adaptHeightToChildren with a StackPanel. However, in my understanding, you should not use these properties as the StackPanel already adapts its height (if vertical = true) or its width (if vertical = false) to its children.

2 Likes

Many thanks @Evgeni_Popov! We greatly appreciate how quickly the BabylonJS team gets fixes published.

Fwiw, it makes complete sense to me that one wouldn’t use the adaptWidthToChildren / adaptHeightToChildren properties on a StackPanel if the StackPanel already adapts size to its children.

I’m upgrading my project to version 4.2.0-beta.1 right now to confirm the fixes (I didn’t see a way to choose this specific version in the playground). I’ll let you know if any issues persist.

BTW @Evgeni_Popov, I think this fix you made may also fix the bug/question I posted last week regarding ScrollViewer.

Ah, I missed that one!

Let me know if that fixes it.

@Evgeni_Popov, I’m running this fix in my project and padding in TextBlocks feel a lot more stable now. It would be very easy to test each case if there was a way to run my playground example with v4.2.0-beta.1, but I’m not sure that’s possible.

There’s still an issue with the width of a TextBlock inside of a StackPanel. I created another playground to demonstrate the issue, but please note it needs to be tested with v4.2.0-beta.1 to see the issue I’m experiencing.

Here’s what it looks like in the current playground in v4.2.0-alpha.35:

And here’s what the same code looks like in my test project using v4.2.0-beta.1:


Note the TextBlocks are too wide and get clipped by the StackPanel.

I also threw one of the TextBlocks into a container, just in case this issue was specific to a TextBlock being a direct child of a StackPanel, but it didn’t change the outcome. It was still overflowing and clipped.

Let me know if you have any questions or cannot recreate this issue. Thanks!

I think your PG is not the right one, I see that:
image

Note: the Playground is in 4.2.0-beta.1:

Whoops, you are correct. I have edited my original post with the correct link of that playground. Link is also below.

https://www.babylonjs-playground.com/#QIMS86#1

It does display correctly for me in the Playground:

Hmm… that certainly looks correct in your screenshot. Is there a way I can force the playground to use 4.2.0-beta.1 on my side?

Use CTRL+F5 in Chrome to clear the cache: I think it’s a cache problem.

Dang, Chrome really doesn’t want to update, I’ve even been working with the cache disabled. But I was able to get the latest Engine in other browsers.

The playground example appears to be working perfectly! I’m not sure what’s different about my project than the playground, but I should be able to troubleshoot it now. Thanks!

2 Likes

Hey @Evgeni_Popov, I figured out my issue. In the playground, I was explicitly setting the StackPanel’s width to 100% whereas in my project I was letting it default to 100%.

I don’t know if this is a bug or its intended behavior, but if the StackPanel’s width is unset and defaults to 100% (which can be confirmed by inspecting the StackPanel), the calculated width will be incorrect.

Here’s a new playground demonstrating this. You’ll see that the StackPanel shows width 100% but it still gets clipped.

I would say this one is the intended behaviour.

By default, the stack panel is set to not handle the width/height “manually”, so some of the code handling measurement is not executed in this case but delegated to some other parts of the GUI.

If you set the width, it means you want StackPanel to handle the width “manually”, and in that case everything will work as you expect.

@Deltakosh Are you ok with that?

totally. This is the spirit of the StackPanel

1 Like