Learn / UI & GFX

Build a Scrolling Item List

Build an automatically sized scrolling list with selectable rows and sample item data.

Prefer to watch? 6 hand-picked UI & GFX videos →

Beginner3 min readBy Joseph San Nicolas

Create an item list that grows as you add rows. Selecting an item updates a label. This is a local UI exercise with sample data, not a saved inventory or purchase system.

1. Prepare the screen

Create a ScreenGui named ListGui directly inside StarterGui. Set ScreenInsets to CoreUISafeInsets. Insert one LocalScript into ListGui. The script below creates the rest of the interface, so you do not need to add rows by hand.

2. Create the list and rows

Paste this complete script into the LocalScript:

local gui = script.Parent

local panel = Instance.new("Frame")
panel.AnchorPoint = Vector2.new(0.5, 0.5)
panel.Position = UDim2.fromScale(0.5, 0.5)
panel.Size = UDim2.fromScale(0.9, 0.8)
panel.BackgroundColor3 = Color3.fromRGB(30, 33, 40)
panel.Parent = gui

local limit = Instance.new("UISizeConstraint")
limit.MaxSize = Vector2.new(560, 500)
limit.Parent = panel

local selected = Instance.new("TextLabel")
selected.Position = UDim2.fromOffset(12, 8)
selected.Size = UDim2.new(1, -24, 0, 40)
selected.BackgroundTransparency = 1
selected.TextColor3 = Color3.new(1, 1, 1)
selected.TextSize = 18
selected.TextWrapped = true
selected.Text = "Select an item"
selected.Parent = panel

local list = Instance.new("ScrollingFrame")
list.Name = "Items"
list.Position = UDim2.fromOffset(12, 56)
list.Size = UDim2.new(1, -24, 1, -68)
list.BackgroundTransparency = 1
list.BorderSizePixel = 0
list.CanvasSize = UDim2.fromOffset(0, 0)
list.AutomaticCanvasSize = Enum.AutomaticSize.Y
list.ScrollingDirection = Enum.ScrollingDirection.Y
list.ScrollBarThickness = 6
list.Parent = panel

local layout = Instance.new("UIListLayout")
layout.SortOrder = Enum.SortOrder.LayoutOrder
layout.Padding = UDim.new(0, 8)
layout.Parent = list

for index = 1, 20 do
    local itemName = "Sample item " .. index
    local row = Instance.new("TextButton")
    row.Name = "Item" .. index
    row.Size = UDim2.new(1, -12, 0, 48)
    row.LayoutOrder = index
    row.BackgroundColor3 = Color3.fromRGB(55, 60, 72)
    row.TextColor3 = Color3.new(1, 1, 1)
    row.TextSize = 18
    row.Text = itemName
    row.Parent = list

    row.Activated:Connect(function()
        selected.Text = "Selected: " .. itemName
    end)
end

3. Understand the two sizes

The panel and list Size values define the visible area. AutomaticCanvasSize expands the area inside the list as content grows. UIListLayout places each row below the previous one, using LayoutOrder for predictable ordering.

The rows have fixed pixel heights and flexible widths. Their 12-pixel width allowance keeps the text clear of the scrollbar. Avoid making row height a fraction of a canvas whose height those same rows determine.

4. Test adding and removing content

Run the game and scroll to Sample item 20. Select it and confirm the label changes. Stop the test, change the loop count to 3, and run again. The interface should no longer need the long scroll area.

Repeat on a phone emulator and test dragging the list as well as tapping a row. For real data, generate rows from your item table and rebuild or update them when that data changes.

Troubleshooting

  • Rows overlap: check that UIListLayout is inside Items.
  • Ordering looks wrong: set SortOrder to LayoutOrder and assign each row a number.
  • Large blank scroll area: check that CanvasSize starts at zero.
  • Selection does not award an item: this lesson only updates presentation. Validate actual inventory changes on the server.