Skip to content

Commit

Permalink
When no clearance applies to an element with clear set, place the e…
Browse files Browse the repository at this point in the history
…lement below the float just as we would if it was `clear:none`

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

Reviewed by Antti Koivisto.

This patch aligns WebKit with Blink / Chromium and Gecko / Firefox.

Merge: https://chromium.googlesource.com/chromium/blink/+/502ffded2efe7d27b5e0ec085a47d4764b65c12c

If an element has 'clear' set but we don't actually calculate clearance
for it then it should be placed as though it had 'clear:none'. This is
especially pertinent when the element has margin-top that puts it clear of any float.

The relevant web-specification [1] is:

"Computing the clearance of an element on which clear is set is done by ..."

[1] https://drafts.csswg.org/css2/#clearance

* Source/WebCore/rendering/RenderBlockFlow.cpp:
(RenderBlockFlow::marginBeforeEstimateForChild):
* LayoutTests/fast/block/float/element-clears-float-without-clearance.html: Add Test Case
* LayoutTests/fast/block/float/element-clears-float-without-clearance-expected.html: Add Test Case Expectation

Canonical link: https://commits.webkit.org/270525@main
  • Loading branch information
Ahmad-S792 authored and Ahmad Saleem committed Nov 10, 2023
1 parent ecc0e56 commit f5f625b
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<!DOCTYPE html>
<style>
.bfc {
overflow:hidden;
border:solid;
margin-top:1em;
}

.float {
background-color: aqua;
height: 30px;
display:inline-block;
}

.under {
height: 50px;
background-color: orange;
}

.clear {
margin-top:20px;
height: 50px;
background-color: orange;
}
section {
float: left;
width: 25%;
margin: 0 5px;
padding: 5px;
background: #ddd;
}
</style>
<section>
crbug.com/434048 : The orange boxes should sit right under the float.
<div class="bfc">
<div class="float">float</div>
<div class="under">clear</div>
</div>

<div class="bfc">
<div class="float">float</div>
<div class="under">clear</div>
</div>

<div class="bfc">
<div class="float">float</div>
<div class="under">clear</div>
</div>
</section>

<section>
crbug.com/434048 : There should be 20px between the orange box and the float.
<div class="bfc">
<div class="float">float</div>
<div class="clear">clear</div>
</div>

<div class="bfc">
<div class="float">float</div>
<div class="clear">clear</div>
</div>

<div class="bfc">
<div class="float">float</div>
<div class="clear">clear</div>
</div>
</section>

<section>
crbug.com/434048 : There should be 20px between the orange box and the float.
<div class="bfc">
<div class="float">float</div>
<div class="clear">clear</div>
</div>

<div class="bfc">
<div class="float">float</div>
<div class="clear">clear</div>
</div>

<div class="bfc">
<div class="float">float</div>
<div class="clear">clear</div>
</div>
</section>
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<!DOCTYPE html>
<style>
.bfc {
overflow:hidden;
border:solid;
margin-top:1em;
}

.float {
background-color: aqua;
float: left;
height: 30px;
}

.clear {
clear:left;
margin-top:50px;
height: 50px;
background-color: orange;
}
section {
float: left;
width: 25%;
margin: 0 5px;
padding: 5px;
background: #ddd;
}

</style>
<section>
crbug.com/434048 : The orange boxes should sit right under the float.
<div class="bfc">
<div>
<div class="float">float</div>
<div>
<div class="clear">clear</div>
</div>
</div>
</div>

<div class="bfc">
<div>
<div class="float">float</div>
<div class="clear">clear</div>
</div>
</div>

<div class="bfc">
<div>
<div>
<div class="float">float</div>
</div>
<div class="clear">clear</div>
</div>
</div>
</section>

<section>
crbug.com/434048 : There should be 20px between the orange box and the float.
<div class="bfc">
<div>
<div class="float">float</div>
</div>
<div class="clear">clear</div>
</div>

<div class="bfc">
<div class="float">float</div>
<div style="margin-top: 30px;">
<div>
<div class="clear">clear</div>
</div>
</div>
</div>

<div class="bfc">
<div class="float">float</div>
<div style="margin-top: 10px;">
<div>
<div class="clear">clear</div>
</div>
</div>
</div>
</section>

<section>
crbug.com/434048 : There should be 20px between the orange box and the float.
<div class="bfc">
<div class="float">float</div>
<div>
<div class="clear">clear</div>
</div>
</div>

<div class="bfc">
<div class="float">float</div>
<div style="margin-top: 40px;">
<div class="clear">clear</div>
</div>
</div>

<div class="bfc">
<div class="float">float</div>
<div class="clear">clear</div>
</div>
</section>
9 changes: 7 additions & 2 deletions Source/WebCore/rendering/RenderBlockFlow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1592,8 +1592,7 @@ void RenderBlockFlow::marginBeforeEstimateForChild(RenderBox& child, LayoutUnit&
break;
}

// Give up if there is clearance on the box, since it probably won't collapse into us.
if (!grandchildBox || RenderStyle::usedClear(*grandchildBox) != UsedClear::None)
if (!grandchildBox)
return;

// Make sure to update the block margins now for the grandchild box so that we're looking at current values.
Expand All @@ -1606,6 +1605,12 @@ void RenderBlockFlow::marginBeforeEstimateForChild(RenderBox& child, LayoutUnit&
}
}

// If we have a 'clear' value but also have a margin we may not actually require clearance to move past any floats.
// If that's the case we want to be sure we estimate the correct position including margins after any floats rather
// than use 'clearance' later which could give us the wrong position.
if (RenderStyle::usedClear(*grandchildBox) != UsedClear::None && !childBlock.marginBeforeForChild(*grandchildBox))
return;

// Collapse the margin of the grandchild box with our own to produce an estimate.
childBlock.marginBeforeEstimateForChild(*grandchildBox, positiveMarginBefore, negativeMarginBefore);
}
Expand Down

0 comments on commit f5f625b

Please sign in to comment.