Touch targets should be at least 48dp by 48dp and must be at least 24dp by 24dp.
These minimum sizes are required to support WCAG Success Criterion 2.5.8 Target Size (Minimum) (Level AA), WCAG Success Criterion 2.5.5 Target Size (Level AAA), and the Material Design Guidelines Touch targets.
There are several techniques for achieving an appropriate visible target size on an interactive composable.
Compose automatically sizes clickable components to an appropriate minimum size, as long as onClick is non-null. This is the preferred approach when you know the click handler is non-null.
For example:
OutlinedIconButton(
onClick = {
// ... onClick must be non-null for this to work
}
) {
Icon(
painter = painterResource(R.drawable.add_24dp),
contentDescription = "Add"
)
}Where you need to be most aware of this behavior is when onClick (or its equivalent) must be set to null, because that can cause a composable's size to shrink unexpectedly.
For example, when correctly implementing a Checkbox inside a Row to associate it with a Text label, the inner Checkbox must set onCheckedChange = null. That will cause the size of the Checkbox to visibly shrink, since its implicit size has been removed, so one of the following techniques must also be applied to make it appear at a normal size. See Checkbox Controls for example code.
In Material Design 3, Modifier.minimumInteractiveComponentSize() will force the size of a composable to be at least 48dp by 48dp. This is the preferred approach when the click handler may or may not be null, or when the click handler is known to be null, but sizing should be preserved (as in the Checkbox example above).
For example:
OutlinedIconButton(
onClick = nullableOnClickLamba,
modifier = Modifier.minimumInteractiveComponentSize()
) {
Icon(
painter = painterResource(R.drawable.add_24dp),
contentDescription = "Add"
)
}Since Material Design 2 lacks Modifier.minimumInteractiveComponentSize(), use Modifier.defaultMinSize(minWidth = 48.dp, minHeight = 48.dp) or Modifier.sizeIn(minWidth = 48.dp, minHeight = 48.dp) instead.
For example:
OutlinedIconButton(
onClick = nullableOnClickLamba,
modifier = Modifier.defaultMinSize(minWidth = 48.dp, minHeight = 48.dp)
) {
Icon(
painter = painterResource(R.drawable.add_24dp),
contentDescription = "Add"
)
}Touch target size can also be increased by appropriately grouping composables into one clickable composable. One example would be making an entire Card clickable instead of its clickable image and its single interior button when both open the same screen. Grouping an avatar image with a person's name into a single clickable Row or Column within a Card could be another example.
Even when the visible touch target size of an interactive composable is smaller than Material Design's minimum size, Jetpack Compose will also automatically apply an invisible touch target size region around such a composable so that its touch target size is at least 48dp by 48dp.
This implicit touch target sizing can not prevent problems if small interactive composable are crowded together so their touch target regions overlap. So, if interactive elements are not visibly as large as 48dp by 48dp, be sure they are spaced far enough apart to that their touch targets do not overlap.
For example, if two adjacent IconButtons each have the size 24dp by 24dp, they should be separated by a Spacer of at least 24dp width.
(Note: The hard-coded text shown in these examples is only used for simplicity. Always use externalized string resource references in actual code.)
Copyright 2024-2025 CVS Health and/or one of its affiliates
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.