Scaffold in Jetpack Compose — what it is, properties and how it works

Author: IT Sectr Published: 2026-06-29 Reading time: 11 min

Scaffold is a composable function in Jetpack Compose that implements the basic screen structure according to the Material Design specification. Scaffold provides slots for TopAppBar, BottomBar, FloatingActionButton, Drawer and Snackbar. According to Google Android Documentation, 2025, Scaffold is a required element for most screens in Compose applications, as it manages insets for Material Design system components.

Key Takeaways

  • Scaffold is a Material Design screen scaffold that provides slots for TopAppBar, BottomBar, FAB, Drawer and Snackbar with correct insets.
  • ScaffoldState manages the state of Drawer and Snackbar, enabling opening and closing of the side menu and displaying notifications.
  • topBar, bottomBar and floatingActionButton are Scaffold slots for integrating standard Material Design components.
  • drawerGesturesEnabled controls the swipe gesture for opening the side menu, while snackbarHost controls custom Snackbar display.
  • Scaffold automatically manages insets for the status bar and navigation bar through innerPadding.

What is Scaffold in Jetpack Compose

Scaffold is a composable function that implements the screen scaffold according to the Material Design specification. Scaffold is not a container in the traditional sense — it is a layout manager that coordinates the placement of several standard Material components on the screen.

Scaffold manages insets for TopAppBar, BottomBar and FloatingActionButton, as well as system elements — the status bar and navigation bar. This ensures that content does not overlap with system elements and complies with Material Design guidelines.

According to Material Design Guidelines, 2025, Scaffold should be the root element of every application screen. It replaces the deprecated CoordinatorLayout from the View system and provides a simpler, declarative API for building screen layouts.

Basic Scaffold Signature

Scaffold accepts the parameters modifier, scaffoldState, topBar, bottomBar, floatingActionButton, drawerContent, snackbarHost and content. The content parameter receives PaddingValues — insets that the main content must account for.

kotlin
@Composable
fun BasicScaffold() {
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("Home") }
            )
        },
        floatingActionButton = {
            FloatingActionButton(onClick = {}) {
                Icon(Icons.Default.Add, contentDescription = "Add")
            }
        }
    ) { innerPadding ->
        Column(
            modifier = Modifier.padding(innerPadding)
        ) {
            Text("Main content")
        }
    }
}

Scaffold Slots: topBar, bottomBar and floatingActionButton

topBar is the slot for placing the top app bar, typically TopAppBar or LargeTopAppBar. Scaffold automatically adds insets to innerPadding for content so it does not overlap with topBar. TopAppBar can contain a title, a navigation icon and actions.

bottomBar is the slot for the bottom navigation bar. It supports BottomNavigation, BottomAppBar or NavigationBar. Scaffold accounts for bottomBar height when calculating innerPadding for content. According to Material Design Guidelines, 2025, bottomBar should be used on screens with 3–5 navigation points.

floatingActionButton is the slot for the floating action button. Scaffold automatically positions the FAB according to the Material Design specification — in the bottom right corner with correct insets. floatingActionButtonPosition allows moving the FAB to the center of the bottom edge of the screen.

Example with All Slots

In this example, Scaffold uses all the main slots: TopAppBar with a title, BottomBar with three navigation items and FloatingActionButton for the primary action.

kotlin
@Composable
fun FullScaffold() {
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("App") },
                navigationIcon = {
                    IconButton(onClick = {}) {
                        Icon(Icons.Default.Menu, "Menu")
                    }
                }
            )
        },
        bottomBar = {
            NavigationBar {
                NavigationBarItem(
                    icon = { Icon(Icons.Default.Home, "Home") },
                    label = { Text("Home") },
                    selected = true,
                    onClick = {}
                )
                NavigationBarItem(
                    icon = { Icon(Icons.Default.Search, "Search") },
                    label = { Text("Search") },
                    selected = false,
                    onClick = {}
                )
            }
        },
        floatingActionButton = {
            FloatingActionButton(onClick = {}) {
                Icon(Icons.Default.Add, "Add")
            }
        }
    ) { innerPadding ->
        Box(modifier = Modifier.padding(innerPadding)) {
            Text("Screen content")
        }
    }
}

ScaffoldState: Managing Drawer and Snackbar

ScaffoldState is the state object of Scaffold that combines DrawerState and SnackbarHostState. DrawerState manages opening and closing the side menu, while SnackbarHostState manages displaying and hiding the Snackbar. The state is created using rememberScaffoldState() and passed to the scaffoldState parameter.

DrawerState provides open and close methods for programmatic Drawer control. The Drawer state can be open, closed or partially open. drawerGesturesEnabled allows disabling the swipe gesture to open the Drawer, leaving only programmatic opening via a button.

SnackbarHostState manages the Snackbar — temporary notifications at the bottom of the screen. The showSnackbar method displays a Snackbar with a message and an optional action. According to Material Design Guidelines, 2025, Snackbar should be used for brief messages without critically important information.

kotlin
@Composable
fun ScaffoldWithDrawer() {
    val scaffoldState = rememberScaffoldState()
    val scope = rememberCoroutineScope()

    Scaffold(
        scaffoldState = scaffoldState,
        topBar = {
            TopAppBar(
                title = { Text("Menu") },
                navigationIcon = {
                    IconButton(onClick = {
                        scope.launch {
                            scaffoldState.drawerState.open()
                        }
                    }) {
                        Icon(Icons.Default.Menu, "Menu")
                    }
                }
            )
        },
        drawerContent = {
            Column(modifier = Modifier.padding(16.dp)) {
                Text("Item 1")
                Text("Item 2")
            }
        }
    ) { innerPadding ->
        Box(modifier = Modifier.padding(innerPadding)) {
            Text("Content")
        }
    }
}

Building a Screen with Scaffold Example

A complete screen example with Scaffold includes TopAppBar, BottomNavigation, FloatingActionButton and Snackbar for displaying notifications when the FAB is pressed. ScaffoldState is passed to all components for state coordination.

kotlin
@Composable
fun MainScreen() {
    val state = rememberScaffoldState()
    val scope = rememberCoroutineScope()

    Scaffold(
        scaffoldState = state,
        topBar = {
            TopAppBar(
                title = { Text("IT Sectr") },
                actions = {
                    IconButton(onClick = {}) {
                        Icon(Icons.Default.Notifications, "Notifications")
                    }
                }
            )
        },
        bottomBar = {
            NavigationBar {
                NavigationBarItem(icon = { Icon(Icons.Default.Home, "Home") },
                    label = { Text("Home") }, selected = true, onClick = {})
                NavigationBarItem(icon = { Icon(Icons.Default.Settings, "Settings") },
                    label = { Text("Settings") }, selected = false, onClick = {})
            }
        },
        floatingActionButton = {
            FloatingActionButton(onClick = {
                scope.launch {
                    state.snackbarHostState.showSnackbar("Done")
                }
            }) {
                Icon(Icons.Default.Add, "Add")
            }
        }
    ) { padding ->
        Box(
            modifier = Modifier.padding(padding).fillMaxSize(),
            contentAlignment = Alignment.Center
        ) {
            Text("Welcome")
        }
    }
}

InnerPadding and Adaptive Layout with Scaffold

innerPadding is the PaddingValues that Scaffold passes to the content block. They contain insets needed to prevent content from overlapping with statusBar, navigationBar, topBar and bottomBar. Using innerPadding is required for correct display on different devices.

Scaffold automatically calculates innerPadding based on system insets and the height of installed slots. On devices with camera cutouts or display notches, Scaffold adjusts insets for the status bar. On older devices with physical buttons, the bottom inset may be absent.

According to Android Developers, 2024, innerPadding should be applied to the root content container via Modifier.padding(innerPadding). If the content uses a scrollable container, innerPadding is applied via Modifier.consumeWindowInsets for correct keyboard and system gesture behavior.

  • Apply innerPadding to the root content container using Modifier.padding(innerPadding)
  • For scrollable containers use Modifier.consumeWindowInsets(innerPadding)
  • Do not add extra insets for the status bar — Scaffold handles this automatically
  • If topBar or bottomBar is absent, the corresponding insets in innerPadding will be zero

Frequently Asked Questions

How is Scaffold different from a regular Column or Box?

Scaffold is not a container but a layout manager that controls slots for TopAppBar, BottomBar, FAB, Drawer and Snackbar, and also automatically handles insets for system components. Column and Box only position elements without considering Material Design.

Is it mandatory to use Scaffold on every screen?

Scaffold is recommended for screens that use Material Design components. On simple screens without TopAppBar, BottomBar or FAB, Scaffold is not required, but it provides correct system insets via innerPadding, which is useful even without slots.

How do I show a Snackbar through Scaffold?

Pass ScaffoldState to the scaffoldState parameter of Scaffold, then call state.snackbarHostState.showSnackbar(“Message”) inside a coroutine. Scaffold will automatically display the Snackbar at the bottom of the screen.

Can I use Scaffold without scaffoldState?

Yes, Scaffold creates internal state by default if scaffoldState is not passed. However, to programmatically control Drawer and Snackbar, you need to create and pass ScaffoldState via rememberScaffoldState().

How do I change the FloatingActionButton position in Scaffold?

Use the floatingActionButtonPosition parameter of Scaffold. By default, the FAB is located at the bottom right (FabPosition.End). Set FabPosition.Center to place the FAB at the center of the bottom edge of the screen.

Summary

  • Scaffold is a Material Design screen scaffold with slot management for TopAppBar, BottomBar, FAB, Drawer and Snackbar and automatic system insets.
  • topBar, bottomBar and floatingActionButton are Scaffold slots for integrating standard components with correct positioning.
  • ScaffoldState combines DrawerState and SnackbarHostState, providing programmatic control over the side menu and notifications via coroutines.
  • innerPadding is a required parameter of the content block, containing insets for system elements and installed Scaffold slots.
  • drawerGesturesEnabled and floatingActionButtonPosition are additional parameters for fine-tuning Scaffold behavior.
  • Scaffold automatically handles insets for the status bar and navigation bar on devices with different screen configurations.
  • For simple screens without Material components, Scaffold is not required but is recommended as the root element for correct system inset handling.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also