How to create scrolling frames that automatically size CORRECTLY!

Okay, after hours and hours and hours of messing around, I finally figured it out. I posted this as a reply to someones questions previously, so you may already have seen this, but I thought I would make it ‘official’ by posting here.

So, you can make your shop and scrolling frame however you desire, that being scale or offset. Its up to you.

I will use this current GUI I am creating for a church group.

I have found that it is best to create your shop frame with OFFSET. (At least for everything I have created recently). A frame might look really nice on a Laptop, when created with scale, but then when it is put on a phone, it shrinks to a very small size (obviously because scale uses the devices screen size).

This GUI looks great on a laptop, but could you imagine that the picture is on a phone. Imagine how small the GUI will be and trying to click buttons etc. You want the GUI to be nice and big on small devices so that it is easy for mobile users to use:

SINCE I USED OFFSET for the GUI, this is what I get on a mobile device:
This is a lot better, because the GUI is bigger on mobile devices, since I used OFFSET.

HOWEVER, if I used SCALE, this is how tiny it would be on a mobile device:
While the GUI gets messed up because of how small it is, imagine trying to click the tiny buttons on your small mobile device. It would be a nightmare.

There are times when scale would be better, such as covering the whole screen, or when you have a big GUI. But for smaller GUI’s, I am using OFFSET a lot more now.

Now for the next part:

Since your GUI is being created with OFFSET (or with scale), you can just simply use SCALE for the scrolling frame. I find it best to structure the GUIs as such:
In my GUI I have the actual ScreenGUI, then a frame which I make the size that I want for the shop (offset), then I add the constraints that I want, then I create a scrolling frame where I want the items to be (scale).
As long as your first frame that holds everything is sized with OFFSET, you can just make everything from this point on with scale or offset - they will do the same thing.


Fitting an unlimited amount of items in the frame:

I think we all have the issue where we just don’t know how many items will be in the scrolling frame, or maybe you are creating an inventory frame, so there could be 10 items or 200 items. This is where automatic sizing comes in. I have used ROBLOX’s own AutoCanvasSize property and sometimes it does not work; this is where this simple script comes in:

This script works with both UIListLayout and UIGridLayout. When you run the function UpdateCanvasSize(Canvas, Constraint), reference the scrolling frame first, then the constraint you are using (list or grid). I have ‘+20’ for the Y axis in the script because I found that some items got cut off by a small amount, and have never had an issue since I added the ‘+20’. Feel free to remove it, or change according to your GUI.

local function UpdateCanvasSize(Canvas, Constraint)
	Canvas.CanvasSize =, Constraint.AbsoluteContentSize.X, 0, Constraint.AbsoluteContentSize.Y+20)

wait(2) -- I have this wait because I use scripts to import items, so it needs time to wait for all items to come in.

UpdateCanvasSize(script.Parent, script.Parent.UIGridLayout)

Now, once the function runs, you should have a nicely sized scrolling frame that doesn’t have a bunch of white space at the end.


I really hope this helps. If you need any help, please contact me: harrray#6505.
I know ROBLOX scrolling frames can be such a pain (I wish they would do something about it lol). if you need help, Id be more than willing to help, answer questions, or join your team create!

File Download

Here is a file to download in case you need to see something for yourself! Feel free to use this as your template :slight_smile:
GUIScrolling.rbxl (41.1 KB)


Nice! Needed this.


Replace this with



What I do:

  • Set CanvasSize to 0
  • Enable AutoCanvasSize (not sure of the name of the property) only in the Y direction

There, that works for me.


Horrible practice, please architect your scripts properly to run synchronously and in order. You should use ModuleScripts for this.

Never use wait to wait for other code. Have the other code notify you directly and synchronously. You used to be able to use events for this, but ever since Deferred Events you can no longer rely on events to fire in a timely manner. Use callbacks directly or task.spawn.