beforeLayout method
void
beforeLayout()
Implementation
void beforeLayout() {
final RenderObject? effectiveParent = parent is RenderEventListener ? (parent as RenderEventListener).parent : parent;
// In WebF's render tree, CSS boxes can be wrapped by Flutter proxy render objects
// (e.g., semantics/gesture/scroll adapters). Those wrappers can break the direct
// "parent is RenderBoxModel" check, even though the incoming constraints are
// already the correct containing-block size (e.g., grid/flex cell width).
//
// Prefer the incoming constraints whenever they are definite (tight) or when
// we are in a normal CSS parent-child relationship. Flutter proxy parents
// (e.g., Semantics/Scrollable) may still pass tight constraints that represent
// the real containing block size (like grid/flex cells).
//
// Avoid using merely *bounded* constraints from Flutter layout (e.g. Column),
// because that can unintentionally clamp shrink-to-fit widget elements like
// `<flutter-button>` and make them expand to maxWidth.
final bool shouldUseIncomingConstraints =
effectiveParent is RenderBoxModel || constraints.hasTightWidth || constraints.hasTightHeight;
BoxConstraints contentConstraints = shouldUseIncomingConstraints ? constraints : getConstraints();
// When a parent enforces a definite border-box size (e.g., grid/flex cell),
// treat that as the used size for resolving this element's "auto" sizing.
// This ensures descendants resolve percentages and auto widths against the
// actual containing block size, even when CSS boxes are wrapped by Flutter
// proxy render objects (Scrollable/Semantics/etc.).
if (shouldUseIncomingConstraints &&
constraints.hasTightWidth &&
constraints.maxWidth.isFinite &&
renderStyle.width.isAuto &&
// Do not force a definite auto width on flex items. Flex items' main-axis
// size is resolved by the flex formatting context; forcing auto width to
// the container's tight constraint here breaks flex base sizing and can
// collapse sibling flex items (e.g., overflow:hidden + min-width:0 text truncation).
!renderStyle.isParentRenderFlexLayout() &&
renderStyle.position != CSSPositionType.absolute &&
renderStyle.position != CSSPositionType.fixed) {
double contentW = renderStyle.deflatePaddingBorderWidth(constraints.maxWidth);
if (contentW.isFinite && contentW < 0) contentW = 0;
renderStyle.contentBoxLogicalWidth = contentW;
hasOverrideContentLogicalWidth = true;
}
if (shouldUseIncomingConstraints &&
constraints.hasTightHeight &&
constraints.maxHeight.isFinite &&
renderStyle.height.isAuto &&
// See width note above: do not force auto sizes for flex items.
!renderStyle.isParentRenderFlexLayout() &&
renderStyle.position != CSSPositionType.absolute &&
renderStyle.position != CSSPositionType.fixed) {
double contentH = renderStyle.deflatePaddingBorderHeight(constraints.maxHeight);
if (contentH.isFinite && contentH < 0) contentH = 0;
renderStyle.contentBoxLogicalHeight = contentH;
hasOverrideContentLogicalHeight = true;
}
// Deflate border constraints.
contentConstraints =
renderStyle.deflateBorderConstraints(contentConstraints);
// Deflate padding constraints.
contentConstraints =
renderStyle.deflatePaddingConstraints(contentConstraints);
// Fix for text-overflow ellipsis: when content constraints become unbounded
// but the original constraints were bounded, and the element needs ellipsis,
// restore bounded width to allow proper text truncation.
if (renderStyle.effectiveOverflowX != CSSOverflowType.visible &&
renderStyle.effectiveTextOverflow == TextOverflow.ellipsis &&
contentConstraints.maxWidth.isInfinite &&
constraints.hasBoundedWidth) {
// Recalculate the content constraints using the original bounded constraints
BoxConstraints boundedConstraints =
renderStyle.deflateBorderConstraints(constraints);
boundedConstraints =
renderStyle.deflatePaddingConstraints(boundedConstraints);
contentConstraints = BoxConstraints(
minWidth: contentConstraints.minWidth,
maxWidth: boundedConstraints.maxWidth,
minHeight: contentConstraints.minHeight,
maxHeight: contentConstraints.maxHeight,
);
}
this.contentConstraints = contentConstraints;
clearOverflowLayout();
isSelfSizeChanged = false;
// Reset cached CSS baselines before a new layout pass. They will be
// updated by subclasses that can establish inline formatting context
// or have well-defined CSS baselines (e.g., replaced elements).
_cssFirstBaseline = null;
_cssLastBaseline = null;
}