Skip to main content
This example shows how CSS flexbox properties map to Roblox’s UIListLayout and UIFlexItem instances.

Example overview

We’ll create a vertical card layout with:
  • Flexbox container using display: flex
  • Vertical direction with gap spacing
  • Center alignment
  • Flexible children with grow/shrink ratios
1

Write the CSS

Create a flexbox layout with flex children:
layout.css
.container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 16px;
  width: 100%;
  height: 100%;
}

.header {
  background-color: #335fff;
  width: 100%;
  height: 60px;
  flex-shrink: 0;
}

.content {
  background-color: #ffffff;
  width: 100%;
  flex-grow: 1;
  flex-shrink: 1;
}

.footer {
  background-color: #f0f0f0;
  width: 100%;
  height: 40px;
  flex-shrink: 0;
}
2

Compile to Luau

rbx-css compile layout.css -o LayoutSheet.luau
3

Review the output

The generated code creates UIListLayout and UIFlexItem pseudo-instances:
LayoutSheet.luau
-- Auto-generated by rbx-css
-- Source: layout.css

local function createStyleSheet()
  local sheet = Instance.new("StyleSheet")
  sheet.Name = "StyleSheet"

  -- Rule: .container
  do
    local rule = Instance.new("StyleRule")
    rule.Selector = ".container"
    rule.Parent = sheet
    rule:SetProperties({
      Size = UDim2.new(1, 0, 1, 0),
    })
  end

  -- Rule: .container::UIListLayout
  do
    local rule = Instance.new("StyleRule")
    rule.Selector = ".container::UIListLayout"
    rule.Parent = sheet
    rule:SetProperties({
      FillDirection = Enum.FillDirection.Vertical,
      HorizontalAlignment = Enum.HorizontalAlignment.Center,
      VerticalAlignment = Enum.VerticalAlignment.Center,
      Padding = UDim.new(0, 16),
    })
  end

  -- Rule: .header
  do
    local rule = Instance.new("StyleRule")
    rule.Selector = ".header"
    rule.Parent = sheet
    rule:SetProperties({
      BackgroundColor3 = Color3.fromRGB(51, 95, 255),
      Size = UDim2.new(1, 0, 0, 60),
    })
  end

  -- Rule: .header::UIFlexItem
  do
    local rule = Instance.new("StyleRule")
    rule.Selector = ".header::UIFlexItem"
    rule.Parent = sheet
    rule:SetProperties({
      FlexMode = Enum.UIFlexMode.Custom,
      ShrinkRatio = 0,
    })
  end

  -- Rule: .content
  do
    local rule = Instance.new("StyleRule")
    rule.Selector = ".content"
    rule.Parent = sheet
    rule:SetProperties({
      BackgroundColor3 = Color3.fromRGB(255, 255, 255),
      Size = UDim2.new(1, 0, 0, 0),
    })
  end

  -- Rule: .content::UIFlexItem
  do
    local rule = Instance.new("StyleRule")
    rule.Selector = ".content::UIFlexItem"
    rule.Parent = sheet
    rule:SetProperties({
      FlexMode = Enum.UIFlexMode.Custom,
      GrowRatio = 1,
      ShrinkRatio = 1,
    })
  end

  -- Rule: .footer
  do
    local rule = Instance.new("StyleRule")
    rule.Selector = ".footer"
    rule.Parent = sheet
    rule:SetProperties({
      BackgroundColor3 = Color3.fromRGB(240, 240, 240),
      Size = UDim2.new(1, 0, 0, 40),
    })
  end

  -- Rule: .footer::UIFlexItem
  do
    local rule = Instance.new("StyleRule")
    rule.Selector = ".footer::UIFlexItem"
    rule.Parent = sheet
    rule:SetProperties({
      FlexMode = Enum.UIFlexMode.Custom,
      ShrinkRatio = 0,
    })
  end

  return sheet
end

return createStyleSheet

Flexbox mappings

Container properties

display: flex

display: flex generates a ::UIListLayout pseudo-instance on the container.

flex-direction

CSSRoblox UIListLayout
flex-direction: rowFillDirection = Enum.FillDirection.Horizontal
flex-direction: columnFillDirection = Enum.FillDirection.Vertical

justify-content

Controls alignment along the main axis:
CSSRoblox Property (row)Roblox Property (column)
justify-content: flex-startHorizontalAlignment = LeftVerticalAlignment = Top
justify-content: centerHorizontalAlignment = CenterVerticalAlignment = Center
justify-content: flex-endHorizontalAlignment = RightVerticalAlignment = Bottom
justify-content: space-betweenHorizontalFlex = SpaceBetweenVerticalFlex = SpaceBetween
justify-content: space-aroundHorizontalFlex = SpaceAroundVerticalFlex = SpaceAround
justify-content: space-evenlyHorizontalFlex = SpaceEvenlyVerticalFlex = SpaceEvenly

align-items

Controls alignment along the cross axis:
CSSRoblox Property (row)Roblox Property (column)
align-items: flex-startVerticalAlignment = TopHorizontalAlignment = Left
align-items: centerVerticalAlignment = CenterHorizontalAlignment = Center
align-items: flex-endVerticalAlignment = BottomHorizontalAlignment = Right
align-items: stretchItemLineAlignment = StretchItemLineAlignment = Stretch

gap

gap: 16pxPadding = UDim.new(0, 16) Roblox’s UIListLayout uses Padding for gap spacing between items.

flex-wrap

flex-wrap: wrapWraps = true

Child properties

flex-grow

flex-grow: 1 generates a ::UIFlexItem with GrowRatio = 1

flex-shrink

flex-shrink: 0 generates a ::UIFlexItem with ShrinkRatio = 0 Children without explicit flex properties use automatic flex mode.

align-self

.child {
  align-self: center;
}
Generates ::UIFlexItem with ItemLineAlignment = Center, overriding the parent’s align-items.

Horizontal layout example

For a horizontal button group:
.button-group {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  gap: 8px;
}

button {
  width: auto;
  height: auto;
  padding: 8px 16px;
  flex-grow: 1;
}
This creates a row of buttons with automatic sizing and equal growth.

Build docs developers (and LLMs) love