New UIListLayout Flex Features [Beta]

[Update] This feature has been released and is no longer in beta! Flex Features for UIListLayout Client Release

Hi Creators!

We are excited to announce new flex features for UIListLayout, available now in a Studio Beta!

Flex allows your UI content to effortlessly fill a dynamically-sized UI container using these new features:

  • Multiline wrapping :leftwards_arrow_with_hook:
  • Growing items to fill empty space / shrinking items if they don’t fit :straight_ruler:
  • Distributing empty space between elements
  • Custom per-item line alignment options :control_knobs:

Our goal is to make authoring UI across platforms, screen resolutions and aspect ratios much more seamless. Ideally, you should only need to create a single UI that looks amazing everywhere.

Flex allows you to accomplish this goal by allowing your content to grow (on desktop screens :desktop_computer:) or shrink (on mobile :iphone:) to best fit on the user’s display.

Enabling the Beta

To enable this beta in Roblox Studio, follow these simple steps:

  1. Open Roblox Studio and navigate to the “File” menu

  2. Click on “Beta Features”

  3. Enable the “UIListLayout Flex Features” option by checking the corresponding checkbox (see screenshot below) and press Save
    image

  4. Restart Roblox Studio when prompted

How to Use

Let’s look at a simple example of making a “spacer” element that fills empty space in a container.

To accomplish this, let’s create a UIListLayout containing two TextLabels and the “spacer” element, a Frame. Set the TextLabels to a known size, such as 100 x 100px. Then, add a UIFlexItem component to the spacer Frame.

So we have this setup:
image10

Now, set the UIFlexItem.FlexMode = Fill so that the spacer fills the remaining space. If you now resize the parent container, notice that the spacer fills up the extra horizontal space between the two TextLabels:

Shop Example

Here’s an example of a shop layout that uses the new flex features:

Notice that the user can access all the shop items for both small and large screens (with scrolling). On small screens, it’s also important to make sure the text isn’t shrunk too small to read, and buttons aren’t too small to tap on.

Here’s how this UI would look on some different mobile and desktop screens:

Here is the instance tree for this example, with the Flex instances highlighted:

And here are some highlights of the new Flex features we used:

  • The ScrollingFrame has a UIListLayout component with HorizontalFlex=Fill and VerticalFlex=Fill. This tells each item in the list to grow horizontally and vertically to fit the container, if there is room.
  • The UIListLayout has Wraps=true which allows the items to take up multiple lines.
  • The icons have a UIFlexItem component with FlexMode=Custom and GrowFactor=0.5, so they grow half as much as the text (which has GrowFactor=1 by default).
  • Each item has a UISizeConstraint with MinSize of 120px in the Y direction, preventing the height of each item from being squished too much.
  • The shop is wrapped in a ScrollingFrame so that overflowing items can be scrolled to on small screens.
  • The ScrollingFrame has AutomaticCanvasSize=Y so that the canvas is sized to fit the content.

Here’s the placefile if you want to check it out in Studio!

Flex Terminology

  • A flex container is a GuiObject with a UIListLayout child.
  • The flex direction = fill direction is the direction specified by UIListLayout.FillDirection.
  • The cross direction is the direction perpendicular to the fill direction.
  • A flex item is a GuiObject child in a flex container.
  • The basis size is the size of a flex item before stretching/growing is applied.
  • The flex size is the size of a flex item after stretching/growing is applied.
  • A flex line is a rectangle within a container containing multiple flex items. The line’s flex size is the width or height of the container, depending on UIListLayout.FillDirection.
  • The line’s cross size is determined by the largest item cross size in the line. The line’s rectangle always completely contains every item in the line.

Flex API

New UIListLayout Properties

Property Value Options Description
UIListLayout.FillDirection: Enum.FillDirection Horizontal, Vertical (default) The main axis aka flex direction of the layout.
UIListLayout.Wraps: boolean False (default), True If true, allows multiple content lines to be created perpendicular to the FillDirection.
UIListLayout.HorizontalFlex: Enum.UIFlexAlignment None (default), Fill, SpaceAround, SpaceBetween, SpaceEvenly If not None, distribute extra horizontal space using this strategy.
UIListLayout.VerticalFlex: Enum.UIFlexAlignment None (default), Fill, SpaceAround, SpaceBetween, SpaceEvenly If not None, distribute extra vertical space using this strategy.
UIListLayout.ItemLineAlignment: Enum.ItemLineAlignment Automatic (default),Start, Center, End, Stretch Cross-axis alignment of items within each line.

New UIFlexItem Instance

Property Value Options Description
UIFlexItem.FlexMode: Enum.UIFlexMode None (default), Grow, Shrink, Fill, Custom How the parent GuiObject should grow or shrink with available space in the parent UIListLayout.
UIFlexItem.ItemLineAlignment: Enum.ItemLineAlignment Automatic (default),Start, Center, End, Stretch Cross-axis alignment of this specific item within the line.
GrowRatio: float Positive number If FlexMode=Custom, and there is empty space in the line, this is the weighting factor for distributing the empty space to this specific item in order to fill the line.This property is only shown in Studio if FlexMode=Custom.
ShrinkRatio: float Positive number If FlexMode=Custom, and there is overflow in the line, this is the weighting factor for shrinking this specific item in order to fit all items in 1 line. This property is only shown in Studio if FlexMode=Custom.

New Enums

UIFlexAlignment

Enum. UIFlexAlignment Value Description
None (default) If set in the flex direction, set each item flex size to have GrowRatio=ShrinkRatio=0. This means that each item will not grow or shrink based on the container size.
If set in the cross direction, set each line cross size to have GrowRatio=ShrinkRatio=0. So each line will not grow/shrink based on the container size.
This is the default for backwards-compatibility with existing UIListLayouts.
Fill If set in the flex direction, set each item flex size to have an effective GrowRatio=ShrinkRatio=1:

If set in the cross direction, stretch each line cross size to fill the container:
SpaceAround If set in the flex direction, distribute empty space between each item as padding. The start and end padding is half the between-element padding.

If set in the cross direction, distribute empty space between each line using the same strategy.
SpaceBetween If set in the flex direction, distribute space between each item in the flex direction. The start and end padding is zero.

If set in the cross direction, distribute empty space between each line using the same strategy.
SpaceEvenly If set in the flex direction, distribute space evenly between each item in the flex direction. The start and end padding is equal to the between-element padding.

If set in the cross direction, distribute empty space between each line using the same strategy.

ItemLineAlignment

Enum.ItemLineAlignment Value Description
Automatic (default) Follow the UIListLayout.HorizontalAlignment or UIListLayout.VerticalAlignment, depending on the flex direction.
If HorizontalFlex/VerticalFlex=Fill for in the flex direction, choose “Stretch” line alignment.
This is the default value for backwards-compatibility.
Start Align items within each line to the top for FillDirection.Horizontal or left for FillDirection.Vertical.
Center Align items in each line to the center of the line.
End Align items in each line to the bottom for FillDirection.Horizontal, or right for FillDirection.Vertical.
Stretch Fill entire line cross direction, overriding the original item cross size.

UIFlexMode

Enum.UIFlexMode Value Effective GrowRatio Effective ShrinkRatio
None (default) 0 0
Grow 1 0
Shrink 0 1
Fill 1 1
Custom UIFlexItem.GrowRatio UIFlexItem.ShrinkRatio

Interaction with AutomaticSize

  • If AutomaticSize is enabled for a UIListLayout child in the flex direction, this is interpreted as “automatic flex basis”. This is implemented by first calculating the minimum size of this item needed to contain its content, and setting this as the “flex basis” size. Then, we allow the item to further grow/shrink based on available space.
  • If AutomaticSize is enabled for a UIListLayout child in the cross direction, this is interpreted as “automatic cross size”. The automatic cross size is calculated as the minimum size needed to contain all the child’s content in the cross direction after the flex size is determined.

Known Issues

  • Automatic Size isn’t supported for nested UIListLayouts with flex features enabled. [Fixed]
  • Flex-enabled UIListLayouts may take multiple frames to update, depending on layout complexity. [Fixed]

Please note that the new Flex features are currently only available in Roblox Studio during the beta period, so these features aren’t active on the Roblox Client yet.

Thanks to @EGOTISMS @uiuxartist @Slim_Fandango for their contributions to this feature!
 

As always, please share any questions or feedback below — we’re eager to know what you think! Thank you.

616 Likes

This topic was automatically opened after 9 minutes.

This is so cool!
It will make organizing dynamic UIs and worrying about cross platform support so much niftier and easy, wow.
I really hope to see more UI feature updates like this in the future.

Also big props for the fantastic post explaining how it works, it made it very comprehensive and helpful!

59 Likes

Wow!!! A much requested feature, this will make dynamically generated UI’s so much better and easier! Thank you to everyone who made this!!

35 Likes

Great update, so happy to see Roblox is making changes to improve developing user interface on all devices.

32 Likes

Finally we can make dynamic UIs.

27 Likes

Awesome, making responsive GUI less painful one step at a time. Though, I hope that SurfaceGui support will be improved for UIScale as the UI fails to update its size on time causing various sizing issues.

27 Likes

Finally! I’ve wanted something like this for so long. (no more carelessly dragging ui into random positions until it looks like it aligns!)

Thank you Roblox! I will definitely be using this.

28 Likes

Fantastic, been looking for something like this to help with aligning uis without finagling with the settings!

25 Likes

by far one of the best updates to hit the platform recently, the lack of flex layouts has probably been my single biggest pain point coming from web dev :raised_hands:

22 Likes

FINALLY THE GOSPEL HAS BEEN SPOKEN

THANK YOU :palms_up_together: :bangbang:

image

47 Likes

this is very cool and useful, i hope this help so many designers

18 Likes

Wow, this is powerful! I really love improvements to already great tools!! I’ve had moments where I wish I could have a “Spacer”, now we do! :grin:

17 Likes

Phenomenal upgrade to the future of interfaces, will be using in my games to further improve multiple user devices and create better opportunities for multiple types of devices to use our experience.

16 Likes

THANK YOU!

This has been a long-needed feature, and this will massively change GUIs, making them better and more detailed

Are there any plans for even more UI Layouts?

11 Likes

This is a really nice feature!! Will definitely be making extensive use of it in my projects!

11 Likes

Will this feature be available for UIGridLayout too?

10 Likes

POV: you just revolutionized how GUI’s work

10 Likes

This timing is beyond convenient for me. Thank you

16 Likes

Cant wait to get home and test this out! I hated how my UI would shrink on mobile. Thank you!

8 Likes