Skip to main content

Positioning and Layouts in Slint

Introduction

All visual elements in Slint are placed in a window.

  • x and y → coordinates relative to their parent.
  • width and height → element size.

Slint calculates absolute position by adding parent positions recursively up to the top-level element.

Placement Methods

You can position elements in two ways:

  1. Explicitly — set x, y, width, and height directly.
  2. Automatically — use layout elements.

Explicit placement is ideal for static UIs; layouts are better for scalable and complex UIs.

Explicit Placement Example

export component Example inherits Window {
width: 200px;
height: 200px;
Rectangle {
x: 100px;
y: 70px;
width: parent.width - self.x;
height: parent.height - self.y;
background: blue;
Rectangle {
x: 10px;
y: 5px;
width: 50px;
height: 30px;
background: green;
}
}
}

Units

  • px → logical pixels (scales with device pixel ratio).
  • phx → physical pixels.
  • % → percentage of parent’s size.

Defaults:

  • x and y center elements by default.
  • width/height vary:
    • Content elements (Text, Image, etc.) → size to content.
    • Elements without content (Rectangle, TouchArea) → fill parent.

Preferred Size

  • Set with preferred-width / preferred-height.
  • Defaults depend on children unless explicitly set.
  • 100% → match parent size.

Example:

export component MyComponent {
preferred-width: 100%;
preferred-height: 100%;
}

Automatic Placement with Layouts

Slint layout elements:

  • VerticalLayout
  • HorizontalLayout
  • GridLayout

Constraints:

  • Size: min-width, min-height, max-width, max-height, preferred-width, preferred-height.
  • Stretch: horizontal-stretch, vertical-stretch (default 0 = no stretch).

Common layout properties:

  • spacing → space between children.
  • padding → space inside layout borders (can be per-side).

Vertical and Horizontal Layout Examples

Stretch by default:

export component Example inherits Window {
width: 200px;
height: 200px;
HorizontalLayout {
Rectangle { background: blue; min-width: 20px; }
Rectangle { background: yellow; min-width: 30px; }
}
}

Alignment:

HorizontalLayout {
alignment: start;
Rectangle { background: blue; min-width: 20px; }
Rectangle { background: yellow; min-width: 30px; }
}

Nested Layouts:

HorizontalLayout {
Rectangle { background: green; width: 10px; }
VerticalLayout {
padding: 0px;
Rectangle { background: blue; height: 7px; }
Rectangle {
border-color: red; border-width: 2px;
HorizontalLayout {
Rectangle { border-color: blue; border-width: 2px; }
Rectangle { border-color: green; border-width: 2px; }
}
}
}
}

Relative Lengths

Use percentages:

width: parent.width * 50%;
height: parent.height * 50%;

Shorthand:

width: 50%;
height: 50%;

Alignment Options

alignment values:

  • stretch (default)
  • start
  • end
  • center
  • space-between
  • space-around

Stretch Algorithm

  1. Elements sized to min size.
  2. Extra space shared by stretch factor.
  3. Does not exceed max size.

Looping in Layouts

Layouts can use for or if to dynamically insert elements:

HorizontalLayout {
Rectangle { background: green; }
for t in [ "Hello", "World" ] : Text { text: t; }
}

GridLayout

Arrange elements in a grid.

With Row:

GridLayout {
Row {
Rectangle { background: red; }
Rectangle { background: blue; }
}
}

With row / col:

GridLayout {
Rectangle { background: red; }
Rectangle { background: blue; col: 1; }
}

Container Components with @children

Control where child elements go:

component BoxWithLabel inherits GridLayout {
Row { Text { text: "label text here"; } }
Row { @children }
}