[csswg-drafts] [css2] 2 elements may get clearance, 1 suffices to avoid floats, how to pick? (#9013)

Loirooriol has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css2] 2 elements may get clearance, 1 suffices to avoid floats, how to pick? ==
I want to properly implement https://drafts.csswg.org/css2/#clearance on Servo but I'm not sure about this:

```html
<!DOCTYPE html>
<div style="float: left; width: 25px; height: 25px; background: cyan"></div>
<div style="height: 50px"></div>
<div id="a" style="clear: both; width: 100px; outline: solid">
  <div id="b" style="clear: both; width: 50px; margin-top: -40px; outline: solid magenta; position: relative"></div>
</div>
```

First, to determine whether `#a` needs clearance, we find its hypothetical position by assuming `clear: none`. However, the result depends on whether `#b` gets clearance or not:

<details><summary><b>Option 1</b>: Assuming <code>#b</code> gets clearance</summary><ul>

Then `#b`'s margin doesn't collapse with `#a`, so we get something like: (position of `#b` still unknown)

![](https://github.com/w3c/csswg-drafts/assets/7477678/07ae29fd-538d-43a1-adf4-3fbe6252cd4e)

The hypothetical position of `#a` is past the relevant float, so no clearance is introduced.

Then we find the hypothetical position of `#b` by assuming `clear: none`, so collapsing the margins:

![](https://github.com/w3c/csswg-drafts/assets/7477678/b38e4d1e-6ac6-42e2-9796-03ff73997aa5)

The hypothetical position of `#b` isn't past the relevant float, so we need to add clearance as we assumed, avoiding margin collapse:

![](https://github.com/w3c/csswg-drafts/assets/7477678/fa94f369-1809-44fe-ad8e-a720a9ce55f6)

The clearance is the amount necessary to place the border edge of the block even with the bottom outer edge of float, that is, 15px. The spec also allows flooring this by the amount necessary to place the top border edge of the block at its hypothetical position, 0px, but this would still result in 15px. Adding this clearance, we finally get

![](https://github.com/w3c/csswg-drafts/assets/7477678/9f83084b-f921-4397-88d3-5d743f945137)

</ul></details>

<details><summary><b>Option 2</b>: Assuming <code>#b</code> doesn't get clearance</summary><ul>

Then the margins collapse and `#a` is moved upwards, overlapping the float: (position of `#b` still unknown)

![](https://github.com/w3c/csswg-drafts/assets/7477678/7ae11a4e-e732-4012-9d87-a94e20ad3a89)

The hypothetical position of `#a` isn't past the relevant float, so we need to add clearance.

The clearance is the amount necessary to place the border edge of the block even with the bottom outer edge of float, that is, 15px. The spec also allows flooring this by the amount necessary to place the top border edge of the block at its hypothetical position, 0px, but this would still result in 15px. Adding this clearance, we get: (position of `#b` still unknown)

![](https://github.com/w3c/csswg-drafts/assets/7477678/5f14802f-b719-4e52-aabf-8caceebbbb68)

Then we find the hypothetical position of `#b` by assuming `clear: none`:

![](https://github.com/w3c/csswg-drafts/assets/7477678/dd35f66d-4370-44b7-a927-abfa94962df1)

The hypothetical position of `#b` is past the relevant float, so no clearance is introduced, as we assumed.

</ul></details>


<details><summary><b>Option 3</b>: Not assuming anything</summary><ul>

Instead, tentatively compute `#b`'s clearance (while still treating `#a` as `clear: none`), then use that information to compute if `#a`'s clearance, and finally compute `#b`'s actual clearance.

So treating both `#a` and `#b` as `clear: none`:

![](https://github.com/w3c/csswg-drafts/assets/7477678/b38e4d1e-6ac6-42e2-9796-03ff73997aa5)

The hypothetical position of `#b` isn't past the relevant float, so we need to add clearance to `#b`. Therefore we proceed as in option 1.

</ul></details>

Blink matches what I expect in options 1/3, Gecko and WebKit match what I expect in option 2.

| Options 1/3<br>(Blink) | Option 2<br>(WebKit, Gecko) |
| - | - |
| ![](https://github.com/w3c/csswg-drafts/assets/7477678/9f83084b-f921-4397-88d3-5d743f945137) | ![](https://github.com/w3c/csswg-drafts/assets/7477678/dd35f66d-4370-44b7-a927-abfa94962df1) |

I guess things would get interesting with options 1 and 2 if we assume that `#b` will get clearance but it ends up not needing it, or viceversa. Option 3 seems best, but more annoying/expensive to implement?



Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/9013 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Tuesday, 27 June 2023 23:13:24 UTC