Compose ConstraintLayout DSL Syntax - androidx/constraintlayout Wiki

A quick reference on how to implement some typical ConstraintLayout cases in Compose.

ConstraintSet DSL vs Modifier DSL

Both syntax work very much alike with a slight difference in setup.


    val constraintSet = ConstraintSet {
        val titleText = createRefFor("title")
        // Helpers are defined in this scope

        constrain(titleText) {
            // constraints, dimensions, transforms
    ConstraintLayout(constraintSet) {
        Text(text = "", modifier = Modifier.layoutId("title"))


    ConstraintLayout {
        val title = createRef()
        // Helpers are defined in this scope

        Text(text = "", modifier = Modifier.constrainAs(title) {
            // constraints, dimensions, transforms


The available API under the ConstrainScope, ie:

constrain(createRefFor("id")) {
    // The API here


Constrain a Composable to another using Anchorable.linkTo()

constrain(title) {
   start.linkTo(parent.start, margin = 10.dp)

Or align a Composable with center...()

constrain(title) {
   centerTo(parent)                          // Center around or inside the given reference
   centerHorizontallyTo(parent, bias = 0.5f) // Constrain start & end to the same anchors at the given reference
   centerVerticallyTo(parent, bias = 0.5f)   // Constrain top & bottom to the same anchors at the given reference

Dimension Behavior

Use androidx.constraintlayout.compose.Dimension to define the dimension behavior of a Composable.

constrain(title) {
   width = Dimension.value(10.dp)

The typical use-cases:

See the Dimension interface documentation for more.


You can use Dimension.ratio(String) to define a dimension as a proportion to the other.

Where the String is a Width:Height ratio.

   height = Dimension.value(10.dp)
   width = Dimension.ratio("4:1")    // The width will be 40dp
// ---------
   width = Dimension.wrapContent
   height = Dimension.ratio("1:0.25")   // The height will be a fourth of the resulting wrapContent width


As with the View system, you can set the visibility of a Composable.

Composables constrained to another with visibility Gone will use goneMargin instead:

constrain(title) {
   visibility = Visibility.Gone
constrain(name) {
   start.linkTo(title.end, margin = 4.dp, goneMargin = 8.dp)  // The margin in the layout will be 8dp



Create horizontal and vertical chains by passing the ConstrainedLayoutReferences of each Composable that should be in the chain. The order each reference is passed will be reflected in the chain.

   // text1 is the head (left-most element) of the chain
   createHorizontalChain(text1, text2, button1, ChainStyle.Packed)

Additionally, chains can be constrained on their axis to reposition them (by default, they are constrained to the parent). Do not try to re-define the constraints for the elements in the chain, it will result in unexpected behavior.

   // text1 start is constrained to parent.start, button1 end is constrained to parent.end
   val chain1 = createHorizontalChain(text1, button1)

   constrain(chain1) {
      // text1 start will now be constrained to vGuideline1

      // button1 end will now be constrained to vGuideline2

   constraint(text1) {
      // DO NOT DO THIS if you wish to constrain the chain to a different element
      // You can however, change the constrains on the axis not managed by the chain


Guidelines can be created with respect to an anchor of the parent (the ConstraintLayout Composable).

And can be defined as a distance from the anchor in Dp, or as a percentage of the total dimension on the respective axis.

   // located at 10dp from the end anchor
   val g1 = createGuidelineFromEnd(10.dp)

   // located at 30% the distance of the total width from the end anchor
   // Eg: for a ConstraintLayout with width of 100dp, the guideline will be at 30dp from the end
   val g2 = createGuidelineFromEnd(0.3f)


Use barriers to be able to constrain to the outermost anchor within a group of elements.

   // The barrier will act as an anchorable point that is always situated
   // at the end-most point of text1 and text2 with an additional 2dp margin
   val barrier1 = createEndBarrier(text1, text2, margin = 2.dp)

   constrain(button1) {
      // The barrier guarantees the button never overlaps with text1 or text2

A barrier can be created for each anchor: