In Jetpack Compose, Modifiers are one of the most powerful tools that allow you to adjust how composables look, behave, and interact with each other. They are the Compose equivalent of XML attributes — but much more flexible and composable.
A Modifier is an immutable object that you attach to a composable
to describe how it should be measured, laid out, drawn, or respond to user input.
You can think of modifiers as a chain of UI transformations applied to a composable.
Text(
text = "Hello Compose!",
modifier = Modifier
.padding(16.dp)
.background(Color.Yellow)
.fillMaxWidth()
.clickable { println("Clicked!") }
)
Here, each modifier adjusts the UI element — applying spacing, color, layout sizing, and click behavior. The order of modifiers matters because they are applied sequentially.
In traditional Android XML, UI attributes were tied to specific widgets. In Compose, however, the goal is to make layout and styling behavior reusable and composable. Modifiers separate what a composable does from how it looks or behaves.
Modifier is defined as a Kotlin interface.then() or the . chaining syntax.padding() – Adds inner space around content.background() – Draws a colored background behind a composable.fillMaxWidth(), fillMaxHeight() – Expands composable to available space.size() / width() / height() – Sets specific dimensions.border() – Draws a border around the composable.clip() – Clips composable content to a shape (e.g., CircleShape).clickable() – Makes composable respond to click gestures.alpha() – Adjusts transparency level.offset() – Moves composable by specified x/y distances.The order in which you apply modifiers affects the final result. Modifiers are evaluated top to bottom in your chain.
// Example 1
Box(
modifier = Modifier
.background(Color.Red)
.padding(16.dp)
)
// Example 2
Box(
modifier = Modifier
.padding(16.dp)
.background(Color.Red)
)
In Example 1, the padding applies inside the red background, while in Example 2, the red background covers the padded area — producing different visuals.
Modifiers are applied as a chain of transformations — each returning a new Modifier.
Internally, Compose uses then() to combine them:
Modifier.padding(8.dp).background(Color.Blue)
// Equivalent to:
Modifier.padding(8.dp).then(Modifier.background(Color.Blue))
This design enables modifier reuse and composition.
You can create your own modifiers using the Modifier.composed() function.
This is useful when you want reusable UI behavior.
fun Modifier.shadowedClickable(onClick: () -> Unit): Modifier = composed {
this
.shadow(4.dp, RoundedCornerShape(12.dp))
.clip(RoundedCornerShape(12.dp))
.background(Color.White)
.clickable(onClick = onClick)
}
Custom modifiers make your UI code more declarative and reusable.
Some composables, like Box or Column,
expose special scope modifiers for aligning or positioning children.
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text("Centered Text")
}
You can also use Modifier.align() inside layout scopes:
Box {
Text(
"Bottom Right",
modifier = Modifier.align(Alignment.BottomEnd)
)
}
remember or rememberUpdatedState for stable references if modifier depends on dynamic state.
Now that you understand modifiers and chaining,
the next article will focus on Basic Layouts —
learning how to build structures using Row, Column, Box, and Spacer composables.