or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdcharts-visualization.mdevents-interaction.mdindex.mdlayout-navigation.mdtheming-styling.mdui-controls.mdutilities-platform.md

layout-navigation.mddocs/

0

# Layout and Navigation

1

2

This document covers Flet's layout system and navigation controls for organizing content and providing app navigation.

3

4

## Import

5

6

```python

7

import flet as ft

8

```

9

10

## Layout Controls

11

12

### Column

13

14

```python { .api }

15

class Column(Control):

16

"""Vertical layout container."""

17

18

def __init__(

19

self,

20

controls: List[Control] = None,

21

alignment: MainAxisAlignment = None,

22

horizontal_alignment: CrossAxisAlignment = None,

23

spacing: float = None,

24

tight: bool = None,

25

wrap: bool = None,

26

run_spacing: float = None,

27

scroll: ScrollMode = None,

28

auto_scroll: bool = None,

29

on_scroll_interval: int = None,

30

on_scroll: callable = None,

31

**kwargs

32

)

33

```

34

35

**Parameters:**

36

- `controls` (List[Control], optional): Child controls to layout vertically

37

- `alignment` (MainAxisAlignment, optional): Vertical alignment of children

38

- `horizontal_alignment` (CrossAxisAlignment, optional): Horizontal alignment of children

39

- `spacing` (float, optional): Vertical spacing between children

40

- `tight` (bool, optional): Whether to tightly fit children

41

- `wrap` (bool, optional): Whether to wrap children to new columns

42

- `scroll` (ScrollMode, optional): Scroll behavior (NONE, AUTO, ALWAYS, HIDDEN)

43

44

**Example:**

45

```python

46

ft.Column([

47

ft.Text("Item 1"),

48

ft.Text("Item 2"),

49

ft.Text("Item 3"),

50

],

51

alignment=ft.MainAxisAlignment.CENTER,

52

horizontal_alignment=ft.CrossAxisAlignment.CENTER,

53

spacing=10)

54

```

55

56

### Row

57

58

```python { .api }

59

class Row(Control):

60

"""Horizontal layout container."""

61

62

def __init__(

63

self,

64

controls: List[Control] = None,

65

alignment: MainAxisAlignment = None,

66

vertical_alignment: CrossAxisAlignment = None,

67

spacing: float = None,

68

tight: bool = None,

69

wrap: bool = None,

70

run_spacing: float = None,

71

scroll: ScrollMode = None,

72

auto_scroll: bool = None,

73

on_scroll_interval: int = None,

74

on_scroll: callable = None,

75

**kwargs

76

)

77

```

78

79

**Parameters:**

80

- `controls` (List[Control], optional): Child controls to layout horizontally

81

- `alignment` (MainAxisAlignment, optional): Horizontal alignment of children

82

- `vertical_alignment` (CrossAxisAlignment, optional): Vertical alignment of children

83

- `spacing` (float, optional): Horizontal spacing between children

84

- `wrap` (bool, optional): Whether to wrap children to new rows

85

86

**Example:**

87

```python

88

ft.Row([

89

ft.Icon(ft.icons.STAR),

90

ft.Text("Favorite"),

91

ft.Switch()

92

],

93

alignment=ft.MainAxisAlignment.SPACE_BETWEEN,

94

vertical_alignment=ft.CrossAxisAlignment.CENTER)

95

```

96

97

### Container

98

99

```python { .api }

100

class Container(Control):

101

"""Single-child container with styling."""

102

103

def __init__(

104

self,

105

content: Control = None,

106

padding: PaddingValue = None,

107

margin: MarginValue = None,

108

alignment: Alignment = None,

109

bgcolor: str = None,

110

gradient: Gradient = None,

111

border: Border = None,

112

border_radius: BorderRadiusValue = None,

113

width: float = None,

114

height: float = None,

115

shadow: BoxShadow = None,

116

blur: Blur = None,

117

image_src: str = None,

118

image_src_base64: str = None,

119

image_fit: ImageFit = None,

120

image_repeat: ImageRepeat = None,

121

image_opacity: float = None,

122

shape: BoxShape = None,

123

clip_behavior: ClipBehavior = None,

124

ink: bool = None,

125

animate: AnimationValue = None,

126

tooltip: str = None,

127

on_click: callable = None,

128

on_long_press: callable = None,

129

on_hover: callable = None,

130

**kwargs

131

)

132

```

133

134

**Key Parameters:**

135

- `content` (Control, optional): Single child control

136

- `padding` (PaddingValue, optional): Internal padding

137

- `margin` (MarginValue, optional): External margin

138

- `alignment` (Alignment, optional): Child alignment within container

139

- `bgcolor` (str, optional): Background color

140

- `border` (Border, optional): Border styling

141

- `border_radius` (BorderRadiusValue, optional): Rounded corners

142

- `width` (float, optional): Container width

143

- `height` (float, optional): Container height

144

145

**Example:**

146

```python

147

ft.Container(

148

content=ft.Text("Hello, World!"),

149

padding=20,

150

margin=10,

151

bgcolor=ft.colors.BLUE_100,

152

border_radius=10,

153

alignment=ft.alignment.center

154

)

155

```

156

157

### Stack

158

159

```python { .api }

160

class Stack(Control):

161

"""Overlay layout container."""

162

163

def __init__(

164

self,

165

controls: List[Control] = None,

166

alignment: Alignment = None,

167

fit: StackFit = None,

168

clip_behavior: ClipBehavior = None,

169

**kwargs

170

)

171

```

172

173

**Parameters:**

174

- `controls` (List[Control], optional): Child controls to stack (later children on top)

175

- `alignment` (Alignment, optional): Default alignment for children

176

- `fit` (StackFit, optional): How to size the stack (LOOSE, EXPAND, PASS_THROUGH)

177

- `clip_behavior` (ClipBehavior, optional): Clipping behavior

178

179

**Example:**

180

```python

181

ft.Stack([

182

ft.Container(

183

width=200, height=200,

184

bgcolor=ft.colors.RED

185

),

186

ft.Positioned(

187

left=50, top=50,

188

child=ft.Container(

189

width=100, height=100,

190

bgcolor=ft.colors.BLUE

191

)

192

)

193

])

194

```

195

196

### Positioned

197

198

```python { .api }

199

class Positioned(Control):

200

"""Positioned child within a Stack."""

201

202

def __init__(

203

self,

204

left: float = None,

205

top: float = None,

206

right: float = None,

207

bottom: float = None,

208

width: float = None,

209

height: float = None,

210

child: Control = None,

211

**kwargs

212

)

213

```

214

215

### ResponsiveRow

216

217

```python { .api }

218

class ResponsiveRow(Control):

219

"""Responsive grid row layout."""

220

221

def __init__(

222

self,

223

controls: List[Control] = None,

224

alignment: MainAxisAlignment = None,

225

vertical_alignment: CrossAxisAlignment = None,

226

spacing: float = None,

227

run_spacing: float = None,

228

columns: int = 12,

229

**kwargs

230

)

231

```

232

233

**Parameters:**

234

- `controls` (List[Control], optional): Child controls with responsive column sizing

235

- `columns` (int, optional): Total columns in grid (default: 12)

236

- Each child control should have a `col` property defining responsive breakpoints

237

238

**Example:**

239

```python

240

ft.ResponsiveRow([

241

ft.Container(

242

ft.Text("25%"),

243

bgcolor=ft.colors.RED,

244

col={"sm": 6, "md": 4, "xl": 3}

245

),

246

ft.Container(

247

ft.Text("50%"),

248

bgcolor=ft.colors.GREEN,

249

col={"sm": 6, "md": 4, "xl": 6}

250

),

251

ft.Container(

252

ft.Text("25%"),

253

bgcolor=ft.colors.BLUE,

254

col={"sm": 12, "md": 4, "xl": 3}

255

)

256

])

257

```

258

259

### GridView

260

261

```python { .api }

262

class GridView(Control):

263

"""Scrollable grid layout."""

264

265

def __init__(

266

self,

267

controls: List[Control] = None,

268

horizontal: bool = None,

269

runs_count: int = None,

270

max_extent: float = None,

271

spacing: float = None,

272

run_spacing: float = None,

273

child_aspect_ratio: float = None,

274

padding: PaddingValue = None,

275

semantic_child_count: int = None,

276

cross_axis_count: int = None,

277

auto_scroll: bool = None,

278

reverse: bool = None,

279

on_scroll_interval: int = None,

280

on_scroll: callable = None,

281

**kwargs

282

)

283

```

284

285

**Parameters:**

286

- `controls` (List[Control], optional): Child controls to display in grid

287

- `runs_count` (int, optional): Number of columns/rows

288

- `max_extent` (float, optional): Maximum extent of each child

289

- `spacing` (float, optional): Spacing between children in main axis

290

- `run_spacing` (float, optional): Spacing between runs

291

- `child_aspect_ratio` (float, optional): Width/height ratio of children

292

293

### ListView

294

295

```python { .api }

296

class ListView(Control):

297

"""Scrollable list layout."""

298

299

def __init__(

300

self,

301

controls: List[Control] = None,

302

horizontal: bool = None,

303

spacing: float = None,

304

item_extent: float = None,

305

first_item_prototype: bool = None,

306

divider_thickness: float = None,

307

padding: PaddingValue = None,

308

auto_scroll: bool = None,

309

reverse: bool = None,

310

on_scroll_interval: int = None,

311

on_scroll: callable = None,

312

**kwargs

313

)

314

```

315

316

**Example:**

317

```python

318

ft.ListView([

319

ft.ListTile(title=ft.Text(f"Item {i}")) for i in range(100)

320

],

321

spacing=10,

322

padding=20)

323

```

324

325

### SafeArea

326

327

```python { .api }

328

class SafeArea(Control):

329

"""Safe area container that avoids system intrusions."""

330

331

def __init__(

332

self,

333

content: Control = None,

334

left: bool = True,

335

top: bool = True,

336

right: bool = True,

337

bottom: bool = True,

338

maintain_bottom_view_padding: bool = None,

339

minimum: PaddingValue = None,

340

**kwargs

341

)

342

```

343

344

## Navigation Controls

345

346

### AppBar

347

348

```python { .api }

349

class AppBar(Control):

350

"""Application bar (top navigation)."""

351

352

def __init__(

353

self,

354

leading: Control = None,

355

leading_width: float = None,

356

automatically_imply_leading: bool = None,

357

title: Control = None,

358

center_title: bool = None,

359

actions: List[Control] = None,

360

elevation: float = None,

361

shadow_color: str = None,

362

surface_tint_color: str = None,

363

shape: OutlinedBorder = None,

364

bgcolor: str = None,

365

foreground_color: str = None,

366

exclude_header_semantics: bool = None,

367

title_spacing: float = None,

368

toolbar_height: float = None,

369

toolbar_opacity: float = None,

370

toolbar_text_style: TextStyle = None,

371

title_text_style: TextStyle = None,

372

**kwargs

373

)

374

```

375

376

**Parameters:**

377

- `leading` (Control, optional): Widget displayed before the title (back button, menu icon)

378

- `title` (Control, optional): Primary title widget

379

- `center_title` (bool, optional): Whether to center the title

380

- `actions` (List[Control], optional): Action buttons displayed after title

381

- `elevation` (float, optional): AppBar shadow elevation

382

- `bgcolor` (str, optional): Background color

383

384

**Example:**

385

```python

386

ft.AppBar(

387

leading=ft.Icon(ft.icons.MENU),

388

title=ft.Text("My App"),

389

center_title=True,

390

bgcolor=ft.colors.SURFACE_VARIANT,

391

actions=[

392

ft.IconButton(ft.icons.SEARCH),

393

ft.IconButton(ft.icons.MORE_VERT)

394

]

395

)

396

```

397

398

### BottomAppBar

399

400

```python { .api }

401

class BottomAppBar(Control):

402

"""Bottom application bar."""

403

404

def __init__(

405

self,

406

content: Control = None,

407

bgcolor: str = None,

408

surface_tint_color: str = None,

409

shadow_color: str = None,

410

elevation: float = None,

411

height: float = None,

412

shape: NotchedShape = None,

413

clip_behavior: ClipBehavior = None,

414

notch_margin: float = None,

415

padding: PaddingValue = None,

416

**kwargs

417

)

418

```

419

420

### NavigationBar

421

422

```python { .api }

423

class NavigationBar(Control):

424

"""Bottom navigation bar with destinations."""

425

426

def __init__(

427

self,

428

destinations: List[NavigationDestination] = None,

429

selected_index: int = 0,

430

bgcolor: str = None,

431

surface_tint_color: str = None,

432

elevation: float = None,

433

shadow_color: str = None,

434

indicator_color: str = None,

435

indicator_shape: OutlinedBorder = None,

436

height: float = None,

437

label_behavior: NavigationBarLabelBehavior = None,

438

overlay_color: str = None,

439

animation_duration: int = None,

440

on_change: callable = None,

441

**kwargs

442

)

443

```

444

445

**Parameters:**

446

- `destinations` (List[NavigationDestination], optional): Navigation destinations

447

- `selected_index` (int, optional): Currently selected destination index

448

- `on_change` (callable, optional): Callback for destination changes

449

450

**Example:**

451

```python

452

def route_change(e):

453

index = e.control.selected_index

454

# Handle navigation based on index

455

456

ft.NavigationBar(

457

destinations=[

458

ft.NavigationDestination(icon=ft.icons.HOME, label="Home"),

459

ft.NavigationDestination(icon=ft.icons.SEARCH, label="Search"),

460

ft.NavigationDestination(icon=ft.icons.PERSON, label="Profile")

461

],

462

on_change=route_change

463

)

464

```

465

466

### NavigationDestination

467

468

```python { .api }

469

class NavigationDestination(Control):

470

"""Navigation bar destination."""

471

472

def __init__(

473

self,

474

icon: str = None,

475

icon_content: Control = None,

476

selected_icon: str = None,

477

selected_icon_content: Control = None,

478

label: str = None,

479

tooltip: str = None,

480

**kwargs

481

)

482

```

483

484

### NavigationRail

485

486

```python { .api }

487

class NavigationRail(Control):

488

"""Side navigation rail."""

489

490

def __init__(

491

self,

492

destinations: List[NavigationRailDestination] = None,

493

selected_index: int = None,

494

extended: bool = None,

495

leading: Control = None,

496

trailing: Control = None,

497

min_width: float = None,

498

min_extended_width: float = None,

499

group_alignment: float = None,

500

label_type: NavigationRailLabelType = None,

501

bgcolor: str = None,

502

elevation: float = None,

503

indicator_color: str = None,

504

indicator_shape: OutlinedBorder = None,

505

on_change: callable = None,

506

**kwargs

507

)

508

```

509

510

### NavigationDrawer

511

512

```python { .api }

513

class NavigationDrawer(Control):

514

"""Navigation drawer (side menu)."""

515

516

def __init__(

517

self,

518

controls: List[Control] = None,

519

selected_index: int = None,

520

bgcolor: str = None,

521

shadow_color: str = None,

522

surface_tint_color: str = None,

523

elevation: float = None,

524

indicator_color: str = None,

525

indicator_shape: OutlinedBorder = None,

526

position: NavigationDrawerPosition = None,

527

tile_padding: PaddingValue = None,

528

on_change: callable = None,

529

**kwargs

530

)

531

```

532

533

### Tabs

534

535

```python { .api }

536

class Tabs(Control):

537

"""Tab container with multiple tabs."""

538

539

def __init__(

540

self,

541

tabs: List[Tab] = None,

542

selected_index: int = 0,

543

animation_duration: int = None,

544

tab_alignment: TabAlignment = None,

545

is_secondary: bool = None,

546

indicator_border_radius: BorderRadiusValue = None,

547

indicator_border_side: BorderSide = None,

548

indicator_color: str = None,

549

indicator_padding: PaddingValue = None,

550

indicator_tab_size: bool = None,

551

divider_color: str = None,

552

divider_height: float = None,

553

label_color: str = None,

554

label_padding: PaddingValue = None,

555

mouse_cursor: MouseCursor = None,

556

overlay_color: str = None,

557

physics: ScrollPhysics = None,

558

splash_border_radius: BorderRadiusValue = None,

559

tab_flex: int = None,

560

unselected_label_color: str = None,

561

scrollable: bool = None,

562

on_change: callable = None,

563

**kwargs

564

)

565

```

566

567

**Parameters:**

568

- `tabs` (List[Tab], optional): List of tab definitions

569

- `selected_index` (int, optional): Currently selected tab index

570

- `scrollable` (bool, optional): Whether tabs can scroll horizontally

571

- `on_change` (callable, optional): Callback for tab changes

572

573

### Tab

574

575

```python { .api }

576

class Tab(Control):

577

"""Individual tab definition."""

578

579

def __init__(

580

self,

581

text: str = None,

582

content: Control = None,

583

icon: str = None,

584

tab_content: Control = None,

585

**kwargs

586

)

587

```

588

589

**Example:**

590

```python

591

ft.Tabs(

592

tabs=[

593

ft.Tab(

594

text="Home",

595

icon=ft.icons.HOME,

596

content=ft.Text("Home content")

597

),

598

ft.Tab(

599

text="Settings",

600

icon=ft.icons.SETTINGS,

601

content=ft.Text("Settings content")

602

)

603

],

604

selected_index=0

605

)

606

```

607

608

### MenuBar

609

610

```python { .api }

611

class MenuBar(Control):

612

"""Menu bar with dropdown menus."""

613

614

def __init__(

615

self,

616

controls: List[Control] = None,

617

style: MenuStyle = None,

618

clip_behavior: ClipBehavior = None,

619

**kwargs

620

)

621

```

622

623

### MenuItemButton

624

625

```python { .api }

626

class MenuItemButton(Control):

627

"""Menu item button."""

628

629

def __init__(

630

self,

631

content: Control = None,

632

leading_icon: str = None,

633

trailing_icon: str = None,

634

style: ButtonStyle = None,

635

close_on_click: bool = True,

636

on_click: callable = None,

637

on_hover: callable = None,

638

on_focus: callable = None,

639

**kwargs

640

)

641

```

642

643

### SubmenuButton

644

645

```python { .api }

646

class SubmenuButton(Control):

647

"""Submenu button with nested menu items."""

648

649

def __init__(

650

self,

651

content: Control = None,

652

leading_icon: str = None,

653

trailing_icon: str = None,

654

controls: List[Control] = None,

655

style: ButtonStyle = None,

656

align_on_right: bool = None,

657

clip_behavior: ClipBehavior = None,

658

menu_style: MenuStyle = None,

659

on_open: callable = None,

660

on_close: callable = None,

661

on_hover: callable = None,

662

on_focus: callable = None,

663

**kwargs

664

)

665

```

666

667

## Cupertino (iOS-Style) Navigation

668

669

### CupertinoAppBar

670

671

```python { .api }

672

class CupertinoAppBar(Control):

673

"""iOS-style app bar."""

674

675

def __init__(

676

self,

677

leading: Control = None,

678

automatically_imply_leading: bool = True,

679

automatically_imply_middle: bool = True,

680

previous_page_title: str = None,

681

middle: Control = None,

682

trailing: Control = None,

683

border: Border = None,

684

bgcolor: str = None,

685

padding: PaddingValue = None,

686

**kwargs

687

)

688

```

689

690

### CupertinoNavigationBar

691

692

```python { .api }

693

class CupertinoNavigationBar(Control):

694

"""iOS-style navigation bar."""

695

696

def __init__(

697

self,

698

destinations: List[CupertinoNavigationDestination] = None,

699

selected_index: int = 0,

700

bgcolor: str = None,

701

inactive_color: str = None,

702

active_color: str = None,

703

border: Border = None,

704

height: float = None,

705

on_change: callable = None,

706

**kwargs

707

)

708

```

709

710

## Layout Best Practices

711

712

### Responsive Design Patterns

713

714

```python

715

# Mobile-first responsive layout

716

def build_responsive_layout():

717

return ft.ResponsiveRow([

718

ft.Container(

719

ft.Text("Sidebar"),

720

bgcolor=ft.colors.BLUE_100,

721

col={"xs": 12, "sm": 12, "md": 3, "lg": 2}

722

),

723

ft.Container(

724

ft.Text("Main Content"),

725

bgcolor=ft.colors.GREEN_100,

726

col={"xs": 12, "sm": 12, "md": 9, "lg": 10}

727

)

728

])

729

```

730

731

### Nested Layouts

732

733

```python

734

# Complex layout composition

735

def build_complex_layout():

736

return ft.Column([

737

# Header

738

ft.Container(

739

ft.Text("Header"),

740

height=60,

741

bgcolor=ft.colors.BLUE

742

),

743

744

# Body with sidebar and content

745

ft.Expanded(

746

ft.Row([

747

# Sidebar

748

ft.Container(

749

ft.Column([

750

ft.Text("Menu Item 1"),

751

ft.Text("Menu Item 2")

752

]),

753

width=200,

754

bgcolor=ft.colors.GREY_100

755

),

756

757

# Main content

758

ft.Expanded(

759

ft.Container(

760

ft.Text("Main Content"),

761

bgcolor=ft.colors.WHITE

762

)

763

)

764

])

765

),

766

767

# Footer

768

ft.Container(

769

ft.Text("Footer"),

770

height=40,

771

bgcolor=ft.colors.BLUE

772

)

773

])

774

```

775

776

### Navigation Patterns

777

778

```python

779

# Tab-based navigation

780

class TabApp:

781

def __init__(self):

782

self.selected_tab = 0

783

784

def tab_changed(self, e):

785

self.selected_tab = e.control.selected_index

786

# Update content based on selected tab

787

788

def build(self):

789

return ft.Column([

790

ft.Tabs(

791

selected_index=self.selected_tab,

792

on_change=self.tab_changed,

793

tabs=[

794

ft.Tab(text="Home", content=self.build_home()),

795

ft.Tab(text="Profile", content=self.build_profile()),

796

ft.Tab(text="Settings", content=self.build_settings())

797

]

798

)

799

])

800

801

# Navigation rail pattern

802

def build_navigation_rail_layout():

803

return ft.Row([

804

ft.NavigationRail(

805

destinations=[

806

ft.NavigationRailDestination(

807

icon=ft.icons.HOME,

808

label="Home"

809

),

810

ft.NavigationRailDestination(

811

icon=ft.icons.SEARCH,

812

label="Search"

813

)

814

],

815

on_change=lambda e: handle_navigation(e.control.selected_index)

816

),

817

ft.VerticalDivider(width=1),

818

ft.Expanded(

819

# Main content area

820

ft.Container(ft.Text("Content Area"))

821

)

822

])

823

```

824

825

### Scrollable Layouts

826

827

```python

828

# Infinite scroll list

829

def build_infinite_scroll():

830

items = [ft.ListTile(title=ft.Text(f"Item {i}")) for i in range(1000)]

831

832

return ft.ListView(

833

controls=items,

834

spacing=0,

835

padding=ft.padding.all(16),

836

auto_scroll=True

837

)

838

839

# Custom scroll behavior

840

def build_custom_scroll():

841

return ft.Column([

842

ft.Container(

843

ft.ListView([

844

ft.Text(f"Scrollable item {i}") for i in range(50)

845

]),

846

height=300,

847

border=ft.border.all(1, ft.colors.GREY)

848

)

849

])

850

```

851

852

This covers the comprehensive layout and navigation system in Flet, enabling you to create sophisticated, responsive user interfaces with proper navigation patterns for any type of application.