layoutPositionedChild static method
void
layoutPositionedChild(
- RenderBoxModel parent,
- RenderBoxModel child, {
- bool needsRelayout = false,
Implementation
static void layoutPositionedChild(RenderBoxModel parent, RenderBoxModel child, {bool needsRelayout = false}) {
BoxConstraints childConstraints = child.getConstraints();
// For absolutely/fixed positioned non-replaced elements with both top and bottom specified
// and height:auto, compute the used border-box height from the containing block when the
// containing block's padding-box height is known. This mirrors the horizontal auto-width
// solver in RenderBoxModel.getConstraints and allows patterns like `top:0; bottom:0`
// overlays to stretch with the container height. Do this only when there are no explicit
// min/max height constraints so we don't override author-specified clamping (e.g., max-height).
final CSSRenderStyle rs = child.renderStyle;
final bool isAbsOrFixed = rs.position == CSSPositionType.absolute || rs.position == CSSPositionType.fixed;
final bool hasExplicitMaxHeight = !rs.maxHeight.isNone;
final bool hasExplicitMinHeight = !rs.minHeight.isAuto;
if (isAbsOrFixed &&
!rs.isSelfRenderReplaced() &&
rs.height.isAuto &&
rs.top.isNotAuto &&
rs.bottom.isNotAuto &&
!hasExplicitMaxHeight &&
!hasExplicitMinHeight &&
parent.hasSize &&
parent.boxSize != null) {
final CSSRenderStyle prs = parent.renderStyle;
final Size parentSize = parent.boxSize!;
final double cbHeight = math.max(
0.0,
parentSize.height -
prs.effectiveBorderTopWidth.computedValue -
prs.effectiveBorderBottomWidth.computedValue,
);
double solvedBorderBoxHeight = cbHeight -
rs.top.computedValue -
rs.bottom.computedValue -
rs.marginTop.computedValue -
rs.marginBottom.computedValue;
solvedBorderBoxHeight = math.max(0.0, solvedBorderBoxHeight);
if (solvedBorderBoxHeight.isFinite) {
childConstraints = BoxConstraints(
minWidth: childConstraints.minWidth,
maxWidth: childConstraints.maxWidth,
minHeight: solvedBorderBoxHeight,
maxHeight: solvedBorderBoxHeight,
);
}
}
// Whether child need to layout
bool isChildNeedsLayout = true;
if (child.hasSize && !needsRelayout && (childConstraints == child.constraints) && (!child.needsLayout)) {
isChildNeedsLayout = false;
}
if (isChildNeedsLayout) {
try {
PositionedLayoutLog.log(
impl: PositionedImpl.layout,
feature: PositionedFeature.layout,
message: () => '<${child.renderStyle.target.tagName.toLowerCase()}> layout start '
'constraints=(${childConstraints.minWidth.toStringAsFixed(1)}..${childConstraints.maxWidth.isFinite ? childConstraints.maxWidth.toStringAsFixed(1) : '∞'}, '
'${childConstraints.minHeight.toStringAsFixed(1)}..${childConstraints.maxHeight.isFinite ? childConstraints.maxHeight.toStringAsFixed(1) : '∞'})',
);
} catch (_) {}
// Should create relayoutBoundary for positioned child.
child.layout(childConstraints, parentUsesSize: false);
try {
final Size s = child.size;
PositionedLayoutLog.log(
impl: PositionedImpl.layout,
feature: PositionedFeature.layout,
message: () => '<${child.renderStyle.target.tagName.toLowerCase()}> layout done size=${s.width.toStringAsFixed(2)}×${s.height.toStringAsFixed(2)}',
);
} catch (_) {}
}
}