offsetLeft property
double
get
offsetLeft
Implementation
double get offsetLeft {
double offset = 0.0;
if (!isRendererAttached) {
return offset;
}
Element? offsetParent = this.offsetParent;
RenderBoxModel? ancestor = offsetParent?.attachedRenderer;
if (offsetParent?.hasScroll == true) {
ancestor = offsetParent?.attachedRendererWrapper;
}
// For sticky positioned elements with body as offsetParent,
// we need to account for scroll position
if (renderStyle.position == CSSPositionType.sticky &&
offsetParent is BodyElement) {
// For sticky elements, we need to calculate their position including scroll
// Get total scroll offset by checking all scroll containers
double totalScrollX = 0.0;
// Check if documentElement has scroll
Element? docElement = ownerDocument.documentElement;
if (docElement != null && docElement.attachedRenderer != null) {
totalScrollX = docElement.scrollLeft;
}
// If no scroll on documentElement, check body
if (totalScrollX == 0.0) {
Element? body = ownerDocument.documentElement?.querySelector(['body']);
if (body != null && body.attachedRenderer != null) {
totalScrollX = body.scrollLeft;
}
}
// Get the sticky element's current position relative to the viewport
RenderBoxModel? renderer = attachedRenderer;
if (renderer != null && renderer.hasSize) {
// For sticky elements, we need to calculate their actual visual position
// Get the position placeholder to find original position
RenderPositionPlaceholder? placeholder =
renderStyle.getSelfPositionPlaceHolder();
if (placeholder != null && placeholder.attached) {
// Get the placeholder's position (original position before sticky)
Offset placeholderOffset = placeholder.getOffsetToAncestor(
Offset.zero, offsetParent.attachedRenderer!,
excludeScrollOffset: true);
// Calculate where the element should be without sticky
double naturalPosition = placeholderOffset.dx - totalScrollX;
// Get sticky constraints
double stickyLeft = renderStyle.left.computedValue;
// Check if element should be stuck
if (naturalPosition < stickyLeft) {
// Element should be stuck at sticky position
return totalScrollX + stickyLeft;
} else {
// Element is in its natural position
return placeholderOffset.dx;
}
}
// Fallback: calculate based on current visual position
RenderBox? viewport = getRootViewport();
if (viewport != null) {
// Get position relative to viewport
Offset viewportOffset =
renderer.localToGlobal(Offset.zero, ancestor: viewport);
// For sticky elements, we need to handle the case where they're stuck
// If the element is at its sticky position (e.g., left: 50px), it's stuck
if (viewportOffset.dx == renderStyle.left.computedValue) {
// Element is stuck at its sticky position
return totalScrollX + viewportOffset.dx;
} else {
// Element is not stuck, calculate its natural position
return viewportOffset.dx + totalScrollX;
}
}
}
}
Offset relative = renderStyle.getOffset(
ancestorRenderBox: ancestor, excludeScrollOffset: true);
offset += relative.dx;
return offset;
}