Skip to content
Permalink
Browse files
Incorrect Static Position of Absolute Positioned Elements inside Rel-…
…Positioned Containers

Incorrect Static Position of Absolute Positioned Elements inside Rel-Positioned Containers
https://bugs.webkit.org/show_bug.cgi?id=247869

Reviewed by Alan Baradlay.

Merge - https://src.chromium.org/viewvc/blink?view=revision&revision=180488 & https://chromium.googlesource.com/chromium/src.git/+/116b2f293d0c16017e63e45cc9a97ee5bfa9b161

Per http://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-width if an
absolute positioned box's 'left' and 'right' values are both auto then it
should position itself as though it is a normal flow box in relation to its
containing block. Where the positioned box's container is a rel-positioned
inline we should disregard any offset created by that inline when
positioning the positioned box's layer.

This bug was spotted during a discussion at
http://lists.w3.org/Archives/Public/www-style/2014Jul/0549.html. The tests
are drawn from that discussion and attributed appropriately.

NOTE - Webkit was not adding any absolute positioned element with a
counter offset similar to Blink but the commit was referenced to update the comment.

* Source/WebCore/rendering/RenderInline.cpp:
(RenderInline::offsetForInFlowPositionedInline): Update Comment and Logic to align with web-specs better
* LayoutTests/fast/css/abs-pos-child-inside-rel-pos-inline-offset-001.html: Added Test Case
* LayoutTests/fast/css/abs-pos-child-inside-rel-pos-inline-offset-001-expected.html: Added Test Case Expectations
* LayoutTests/fast/css/abs-pos-child-inside-rel-pos-inline-001.html: Added Test Case
* LayoutTests/fast/css/abs-pos-child-inside-rel-pos-inline-001-expected.html: Added Test Case Expectations
* LayoutTests/fast/repaint/bugzilla-7235.html: Rebaselined

Canonical link: https://commits.webkit.org/256722@main
  • Loading branch information
Ahmad-S792 authored and Ahmad Saleem committed Nov 16, 2022
1 parent 7cc4b42 commit 106eb5245b22de046dbb84cb58ec01c9317c9625
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 9 deletions.
@@ -0,0 +1,7 @@
<!DOCTYPE HTML>
<style>
div#wrapper { background-color: green; width: 100px; height: 200px; }
</style>
<p>Test passes if there is no red.</p>
<div id="wrapper">
</div>
@@ -0,0 +1,20 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<link rel="author" title="Alan Gresley" href="alan[at]css-class.com">
<link rel="author" title="Boris Zbarsky" href="bzbarsky[at]MIT.EDU">
<link rel="author" title="Greg Whitworth" href="gwhit[at]microsoft.com">
<link rel="author" title="Gérard Talbot" href="www-style[at]gtalbot.org">
<style>
div#wrapper { font: 100px/1 Ahem; /* width: 200px; */ }
div#wrapper span { color: green; border-bottom: 100px solid red; }
div#rel-pos-inline { display: inline; position: relative; }
div#abs-pos { background-color: green; position: absolute; height: 100px; width: 100px; }
</style>
<p>Test passes if there is no red.</p>
<div id="wrapper">
<span>X</span>
<div id="rel-pos-inline">
<div id="abs-pos">
</div>
</div>
</div>
@@ -0,0 +1,12 @@
<!DOCTYPE HTML>
<style>
div#wrapper
{
background-color: green; /* change color to see what happens with position static */
height: 200px;
width: 200px;
}
</style>
<p>Test passes if there is no red.</p>
<div id="wrapper">
</div>
@@ -0,0 +1,47 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<link rel="help" href="http://www.w3.org/TR/CSS21/visudet.html#containing-block-details">
<link rel="help" href="http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width">
<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#relative-positioning">
<link rel="author" title="Alan Gresley" href="alan[at]css-class.com">
<link rel="author" title="Boris Zbarsky" href="bzbarsky[at]MIT.EDU">
<link rel="author" title="Greg Whitworth" href="gwhit[at]microsoft.com">
<link rel="author" title="Gérard Talbot" href="www-style[at]gtalbot.org">
<meta content="If the element has 'position: absolute' and in the case that the ancestor is an inline element, the containing block is the bounding box around the padding boxes of the first and the last inline boxes generated for that element. For relatively positioned elements, 'left' and 'right' move the box(es) horizontally, without changing their size. 'Left' moves the boxes to the right, and 'right' moves them to the left." name="assert">
<meta content="ahem" name="flags">

<style>
div#wrapper
{
font: 100px/1 Ahem;
}
span#first-inline
{
color: green;
border-bottom: 100px solid green;
}
span#second-inline
{
color: green;
border-bottom: 100px solid red;
}
div#rel-pos-inline
{
display: inline;
position: relative;
left: 100px;
}
div#abs-pos
{
color: green; /* change color to see what happens with position static */
position: absolute; /* If I'm position static, then a reference file is of no use */
height: 100px;
width: 100px;
}
</style>
<p>Test passes if there is no red.</p>
<div id="wrapper"><span id="first-inline">X</span><span id="second-inline">X</span>
<div id="rel-pos-inline">
<div id="abs-pos">x</div>
</div>
</div>
@@ -14,6 +14,7 @@
width: 100px;
height: 100px;
background: green;
margin-left: 100px;
}
</style>
<script type="text/javascript">
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2003-2022 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -881,17 +881,11 @@ LayoutSize RenderInline::offsetForInFlowPositionedInline(const RenderBox* child)
blockPosition = layer()->staticBlockPosition();
}

// Per http://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-width an absolute positioned box with a static position
// should locate itself as though it is a normal flow box in relation to its containing block.
if (!child->style().hasStaticInlinePosition(style().isHorizontalWritingMode()))
logicalOffset.setWidth(inlinePosition);

// This is not terribly intuitive, but we have to match other browsers. Despite being a block display type inside
// an inline, we still keep our x locked to the left of the relative positioned inline. Arguably the correct
// behavior would be to go flush left to the block that contains the inline, but that isn't what other browsers
// do.
else if (!child->style().isOriginalDisplayInlineType())
// Avoid adding in the left border/padding of the containing block twice. Subtract it out.
logicalOffset.setWidth(inlinePosition - child->containingBlock()->borderAndPaddingLogicalLeft());

if (!child->style().hasStaticBlockPosition(style().isHorizontalWritingMode()))
logicalOffset.setHeight(blockPosition);

0 comments on commit 106eb52

Please sign in to comment.