Skip to content
Permalink
Browse files
percentage top value of position:relative element not calculated usin…
…g parent's min-height unless height set

https://bugs.webkit.org/show_bug.cgi?id=14762

Reviewed by Julien Chaffraix.

Source/WebCore:

Percentage height "is calculated with respect to the height of the generated box's containing block" says
http://www.w3.org/TR/CSS21/visudet.html#the-height-property and "If the height of the containing block is not
specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the
value computes to 'auto'." So when calculating the used height of a replaced element do not crawl through ancestor
blocks except when traversing anonymous blocks. Ensure that anonymous table cells are not skipped through though.

http://www.w3.org/TR/CSS21/tables.html#height-layout adds "In CSS 2.1, the height of a cell box is the minimum
height required by the content." This height is decided by allowing table cells to report their height as auto.
It's not clear why http://trac.webkit.org/changeset/91242 decided it should no longer do this - doing so caused
us to regress in our rendering of computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor.html.

Tests: fast/block/percent-top-parent-respects-min-height.html
       fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr.html
       fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor.html
       fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr.html
       fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor.html

* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::hasAutoHeightOrContainingBlockWithAutoHeight):
(WebCore):
(WebCore::RenderBoxModelObject::relativePositionOffset):
* rendering/RenderBoxModelObject.h:
(RenderBoxModelObject):
* rendering/RenderReplaced.cpp:
(WebCore::RenderReplaced::hasReplacedLogicalHeight):

LayoutTests:

* fast/block/percent-top-parent-respects-min-height-expected.txt: Added.
* fast/block/percent-top-parent-respects-min-height.html: Added.
* fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-expected.txt: Added.
* fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr-expected.txt: Added.
* fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr.html: Added.
* fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor.html: Added.
* fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-expected.txt: Added.
* fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr-expected.txt: Added.
* fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr.html: Added.
* fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor.html: Added.

Canonical link: https://commits.webkit.org/128303@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@143102 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Robert Hogan committed Feb 16, 2013
1 parent dbb4d10 commit 0a1758ac946c925a7cdeafaffa48f7015ac1acc7
@@ -1,3 +1,21 @@
2013-02-16 Robert Hogan <robert@webkit.org>

percentage top value of position:relative element not calculated using parent's min-height unless height set
https://bugs.webkit.org/show_bug.cgi?id=14762

Reviewed by Julien Chaffraix.

* fast/block/percent-top-parent-respects-min-height-expected.txt: Added.
* fast/block/percent-top-parent-respects-min-height.html: Added.
* fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-expected.txt: Added.
* fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr-expected.txt: Added.
* fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr.html: Added.
* fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor.html: Added.
* fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-expected.txt: Added.
* fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr-expected.txt: Added.
* fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr.html: Added.
* fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor.html: Added.

2013-02-16 Stephen White <senorblanco@chromium.org>

[skia] FEOffset should have a Skia implementation.
@@ -0,0 +1,4 @@
https://bugs.webkit.org/show_bug.cgi?id=14762: There should be no red below.

PASS
PASS
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<style>
div { width: 250px; }
.container {
background: green;
position: relative;
min-height: 200px;
height: 10%;
}
.box {
height: 100px;
position: relative;
top: 50%;
background: blue;
}
.ref {
height: 100px;
position: absolute;
top: 150px;
background: red;
}
</style>
<script src="../../resources/check-layout.js"></script>
</head>
<body onload="checkLayout('.box')">
<p>https://bugs.webkit.org/show_bug.cgi?id=14762: There should be no red below.</p>
<div class="container">
<div class="ref"></div>
<div class="box" data-total-y="0"></div>
</div>
<div class="container" style="-webkit-writing-mode: vertical-lr">
<div class="ref"></div>
<div class="box" data-total-y="100"></div>
</div>
</body>
</html>
@@ -0,0 +1,6 @@
The square below should be 100px by 100px. https://bugs.webkit.org/show_bug.cgi?id=103812 In strict mode, an image with height set to 100% and a fixed height ancestor should expand to its instrinsic height and width. Percentage height "is calculated with respect to the height of the generated box's containing block."



PASS

@@ -0,0 +1,6 @@
The square below should be 100px by 100px. https://bugs.webkit.org/show_bug.cgi?id=103812 In strict mode, an image with height set to 100% and a fixed height ancestor should expand to its instrinsic height and width. Percentage height "is calculated with respect to the height of the generated box's containing block."



PASS

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<style>
img { height: 100%; }
body { height: 400px; margin: 0px; padding: 0px; }
</style>
<script src="../../resources/check-layout.js"></script>
</head>
<body>
<p>The square below should be 100px by 100px.
https://bugs.webkit.org/show_bug.cgi?id=103812
In strict mode, an image with height set to 100% and a fixed height ancestor should expand to its instrinsic height and width.
Percentage height "is calculated with respect to the height of the generated box's containing block." </p>
<br>
<div style="-webkit-writing-mode: vertical-lr;">
<img src="resources/square-blue-100x100.png" onload="checkLayout('img')" data-expected-height=100>
</div>
</body>
</html>
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<style>
img { height: 100%; }
body { height: 400px; }
</style>
<script src="../../resources/check-layout.js"></script>
</head>
<body>
<p>The square below should be 100px by 100px.
https://bugs.webkit.org/show_bug.cgi?id=103812
In strict mode, an image with height set to 100% and a fixed height ancestor should expand to its instrinsic height and width.
Percentage height "is calculated with respect to the height of the generated box's containing block." </p>
<br>
<div>
<img src="resources/square-blue-100x100.png" onload="checkLayout('img')" data-expected-height=100>
</div>
</body>
</html>
@@ -0,0 +1,3 @@
The square below should be 100px by 100px.

PASS
@@ -0,0 +1,3 @@
The square below should be 100px by 100px.

PASS
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<style>
img { height: 100%; }
div { display: table; height: auto; }
body { height: 400px; }
</style>
<script src="../../resources/check-layout.js"></script>
</head>
<body>
The square below should be 100px by 100px.
<!-- https://bugs.webkit.org/show_bug.cgi?id=103812 -->
<!-- In strict mode, an image with height set to 100% and a fixed height ancestor should expand to its instrinsic height and width. -->
<!-- Percentage height "is calculated with respect to the height of the generated box's containing block." -->
<br>
<div style="-webkit-writing-mode: vertical-lr;">
<img src="resources/square-blue-100x100.png" onload="checkLayout('img')" data-expected-height=100>
</div>
</body>
</html>
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<style>
img { height: 100%; }
div { display: table; height: auto; }
body { height: 400px; }
</style>
<script src="../../resources/check-layout.js"></script>
</head>
<body>
The square below should be 100px by 100px.
<!-- https://bugs.webkit.org/show_bug.cgi?id=103812 -->
<!-- In strict mode, an image with height set to 100% and a fixed height ancestor should expand to its instrinsic height and width. -->
<!-- Percentage height "is calculated with respect to the height of the generated box's containing block." -->
<br>
<div>
<img src="resources/square-blue-100x100.png" onload="checkLayout('img')" data-expected-height=100>
</div>
</body>
</html>
@@ -1,3 +1,36 @@
2013-02-16 Robert Hogan <robert@webkit.org>

percentage top value of position:relative element not calculated using parent's min-height unless height set
https://bugs.webkit.org/show_bug.cgi?id=14762

Reviewed by Julien Chaffraix.

Percentage height "is calculated with respect to the height of the generated box's containing block" says
http://www.w3.org/TR/CSS21/visudet.html#the-height-property and "If the height of the containing block is not
specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the
value computes to 'auto'." So when calculating the used height of a replaced element do not crawl through ancestor
blocks except when traversing anonymous blocks. Ensure that anonymous table cells are not skipped through though.

http://www.w3.org/TR/CSS21/tables.html#height-layout adds "In CSS 2.1, the height of a cell box is the minimum
height required by the content." This height is decided by allowing table cells to report their height as auto.
It's not clear why http://trac.webkit.org/changeset/91242 decided it should no longer do this - doing so caused
us to regress in our rendering of computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor.html.

Tests: fast/block/percent-top-parent-respects-min-height.html
fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr.html
fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor.html
fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr.html
fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor.html

* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::hasAutoHeightOrContainingBlockWithAutoHeight):
(WebCore):
(WebCore::RenderBoxModelObject::relativePositionOffset):
* rendering/RenderBoxModelObject.h:
(RenderBoxModelObject):
* rendering/RenderReplaced.cpp:
(WebCore::RenderReplaced::hasReplacedLogicalHeight):

2013-02-16 Stephen White <senorblanco@chromium.org>

[skia] FEOffset should have a Skia implementation.
@@ -368,6 +368,31 @@ static LayoutSize accumulateInFlowPositionOffsets(const RenderObject* child)
return offset;
}

bool RenderBoxModelObject::hasAutoHeightOrContainingBlockWithAutoHeight() const
{
Length logicalHeightLength = style()->logicalHeight();
if (logicalHeightLength.isAuto())
return true;

// For percentage heights: The percentage is calculated with respect to the height of the generated box's
// containing block. If the height of the containing block is not specified explicitly (i.e., it depends
// on content height), and this element is not absolutely positioned, the value computes to 'auto'.
if (!logicalHeightLength.isPercent() || isOutOfFlowPositioned() || document()->inQuirksMode())
return false;

RenderBlock* cb = containingBlock();
while (cb->isAnonymousBlock()) {
if (cb->isTableCell())
return true;
cb = cb->containingBlock();
}

if (!cb->style()->logicalHeight().isAuto() || (!cb->style()->logicalTop().isAuto() && !cb->style()->logicalBottom().isAuto()))
return false;

return true;
}

LayoutSize RenderBoxModelObject::relativePositionOffset() const
{
LayoutSize offset = accumulateInFlowPositionOffsets(this);
@@ -394,13 +419,13 @@ LayoutSize RenderBoxModelObject::relativePositionOffset() const
// calculate the percent offset based on this height.
// See <https://bugs.webkit.org/show_bug.cgi?id=26396>.
if (!style()->top().isAuto()
&& (!containingBlock->style()->height().isAuto()
&& (!containingBlock->hasAutoHeightOrContainingBlockWithAutoHeight()
|| !style()->top().isPercent()
|| containingBlock->stretchesToViewport()))
offset.expand(0, valueForLength(style()->top(), containingBlock->availableHeight(), view()));

else if (!style()->bottom().isAuto()
&& (!containingBlock->style()->height().isAuto()
&& (!containingBlock->hasAutoHeightOrContainingBlockWithAutoHeight()
|| !style()->bottom().isPercent()
|| containingBlock->stretchesToViewport()))
offset.expand(0, -valueForLength(style()->bottom(), containingBlock->availableHeight(), view()));
@@ -247,6 +247,8 @@ class RenderBoxModelObject : public RenderLayerModelObject {

static void clipRoundedInnerRect(GraphicsContext*, const LayoutRect&, const RoundedRect& clipRect);

bool hasAutoHeightOrContainingBlockWithAutoHeight() const;

public:
// For RenderBlocks and RenderInlines with m_style->styleType() == FIRST_LETTER, this tracks their remaining text fragments
RenderObject* firstLetterRemainingText() const;
@@ -233,33 +233,13 @@ bool RenderReplaced::hasReplacedLogicalWidth() const
return firstContainingBlockWithLogicalWidth(this);
}

static inline bool hasAutoHeightOrContainingBlockWithAutoHeight(const RenderReplaced* replaced)
{
Length logicalHeightLength = replaced->style()->logicalHeight();
if (logicalHeightLength.isAuto())
return true;

// For percentage heights: The percentage is calculated with respect to the height of the generated box's
// containing block. If the height of the containing block is not specified explicitly (i.e., it depends
// on content height), and this element is not absolutely positioned, the value computes to 'auto'.
if (!logicalHeightLength.isPercent() || replaced->isOutOfFlowPositioned() || replaced->document()->inQuirksMode())
return false;

for (RenderBlock* cb = replaced->containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
if (cb->isTableCell() || (!cb->style()->logicalHeight().isAuto() || (!cb->style()->top().isAuto() && !cb->style()->bottom().isAuto())))
return false;
}

return true;
}

bool RenderReplaced::hasReplacedLogicalHeight() const
{
if (style()->logicalHeight().isAuto())
return false;

if (style()->logicalHeight().isSpecified()) {
if (hasAutoHeightOrContainingBlockWithAutoHeight(this))
if (hasAutoHeightOrContainingBlockWithAutoHeight())
return false;
return true;
}

0 comments on commit 0a1758a

Please sign in to comment.