Short answer
The parent passes size constraints (Constraints) down to the child, the child determines its own size (Size) and passes it up within those constraints, and then the parent determines the child's positional coordinates (Position/Offset).
Explanation
This strict single-pass protocol (one-pass layout O(N)) guarantees record speed in laying out the screen. The parent passes a BoxConstraints object specifying minWidth, maxWidth, minHeight, and maxHeight. The child can in no case exceed these limits, so it chooses a valid Size and passes it up to the parent in the performLayout() function. The parent then places the child in its position by setting BoxParentData.offset. This explains why an element wrapped in a Container ignores its specified dimensions if the parent imposes tight constraints, such as the whole phone screen.
Code example
// Inside the performLayout method of a custom RenderBox:
@override
void performLayout() {
child?.layout(constraints.loosen(), parentUsesSize: true);
size = constraints.constrain(Size(child?.size.width ?? 0, 100));
(child?.parentData as BoxParentData).offset = const Offset(0, 10);
}Common mistakes
- Assuming that setting width and height in a Container guarantees they are always applied, ignoring that parent constraints override any size that conflicts with them.