osamu
osamu

Reputation: 1112

Flutter container inside a container

I'm practicing with flutter Container these days, and this example I came up with is simply astonishing

I put a Container of size 50x50 inside a Container of size 200x200. Strange is that the inner Container expand to 200x200 even though it has a tight constraint of 50x50.

Here's the code

Container(
  width: 200.0,
  height: 200.0,
  color: Colors.orange,
  child: Container(
    width: 50.0,
    height: 50.0,
    color: Colors.blue,
  ),
)

I expect a small blue box inside a bigger orange box.

Could someone explain why?

Upvotes: 45

Views: 23543

Answers (3)

yugandhar
yugandhar

Reputation: 630

If you want to draw 50 * 50 container inside 200 * 200 container, @Richard Heap answers properly. I try to explain the behaviour internally.

Container inside container without alignment (as per question)

Focus on inner container
Container(
    width: 50.0,
    height: 50.0,
    color: Colors.blue,
  )

How does this translates, Container is just wrapper of several low level widgets, since it's mentioned color, this will translate to ColoredBox, since it's mentioned width and height it'll use to build tight constraints using ConstrainedBox widget. Since ColoredBox is required, it'll wrap with child to get finally

ContrainedBox(constraints: <height, width tight>, child: ColoredBox(...))

With similar logic, with Outside container,

Container(
  width: 200.0,
  height: 200.0,
  color: Colors.orange,
  child: Container(
    width: 50.0,
    height: 50.0,
    color: Colors.blue,
  ),
)

it'll be translated to

ConstrainedBox(
  constraints: <heigh=200, width=200 tight>,
  child: ColoredBox(color: Colors.orange,
    child: ConstrainedBox(
      constraints: <height=50, width=50 tight>,
      child: ColoredBox(color: Colors.blue)
    )
  )
)

Note that we're passing tight constraints here, means minHeight = maxHeight = height. Similarly minWidth = maxWidth = width. Top level ConstrainedBox dictates the all children to be only 200 * 200 - non negotiable.

Detailed explanation:

So top-level ConstrainedBox, asks the Orange ColoredBox to be 200 * 200 (due to tight constraints, it sets minWidth = 200, maxWidth = 200, minHeight = 200, and maxHeight = 200 ), so it draws orange color of 200 * 200. And Orange ColoredBox pass the 200 * 200 tight constraints to inner ConstrainedBox, since it has it's own constraints, it'll apply clamping, during clamping it needs to honour the min, max height/width given by the parent, so it'll use following formula to calculate

minHeight = 50.clamp(200, 200) // result will be 200 for all
maxHeight = 50.clamp(200, 200)
minWidth = 50.clamp(200, 200)
maxWidth = 50.clamp(200, 200)

So the height and width will 200 each. It draws Blue ColoredBox with 200 * 200 on top of Orange ColoredBox.

Container inside container with alignment (as per suggested answer).

Container(
    width: 200.0,
    height: 200.0,
    color: Colors.orange,
    alignment: Alignment.center, // where to position the child
    child: Container(
      width: 50.0,
      height: 50.0,
      color: Colors.blue,
    ),
  ),

The alignment option makes Container to wrap the child with Align widget. so the final translated widget tree is...

ConstrainedBox(
  constraints: <heigh=200, width=200 tight>,
  child: ColoredBox(color: Colors.orange,
    child: Align(
      child: ConstrainedBox(
        constraints: <height=50, width=50 tight>,
        child: ColoredBox(color: Colors.blue)
      )
    )
  )
)

So Align widget need to be 200 * 200 due to constraints passed from the parent - Orange ColoredBox. However, 'Align' won't pass same constraints to the child. So the inner ConstrainedBox will have 50 * 50 constraints on Blue ColoredBox.

Here, Align works as constraints passage gate, it can modify the constraints, up to some limits, since it can position the child relatively wherever it wants, while ConstrainedBox can't position it's children wherever they want, they need pass the constraints to children as they are.

Upvotes: 0

maryam hashemi
maryam hashemi

Reputation: 21

In the code below we created a container that has a child called text and tried to style them a bit to make them look better.

Container(
  width: double.infinity,
  decoration: BoxDecoration(
    color: Colors.amber,
    borderRadius: BorderRadius.circular(15)
  ),
  padding: const EdgeInsets.all(10),
  margin: const EdgeInsets.all(10),
  child: const Text('orange juice is very delicious',
     textAlign: TextAlign.center,
     style: TextStyle(
       color: Colors.white,
       fontSize: 22,
       fontWeight: FontWeight.bold
     ),
  ),
),

Upvotes: 0

Richard Heap
Richard Heap

Reputation: 51750

You need to specify where in the orange box you would like the blue box displayed, otherwise the blue box will grow to the size of its parent.

  Container(
    width: 200.0,
    height: 200.0,
    color: Colors.orange,
    alignment: Alignment.center, // where to position the child
    child: Container(
      width: 50.0,
      height: 50.0,
      color: Colors.blue,
    ),
  ),

Upvotes: 110

Related Questions