[csswg-drafts] Negative outline-offset is not interoperable and spec is not clear (#8786)

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

== Negative outline-offset is not interoperable and spec is not clear ==
I'm implementing `outline-offset` in servo-2020, but this is just a big mess. Consider

```html
<div style="width: 100px; height: 100px; border-radius: 100% 0 0 0; background: cyan; outline: 10px solid magenta"></div>
```

Then add some `outline-offset`:

| `outline-offset`  | Expected                                                                                                  | Firefox                                                                                                   | Chromium                                                                                                  | WebKit                                                                                                    |
| :---:             | :---:                                                                                                     | :---:                                                                                                     | :---:                                                                                                     | :---:                                                                                                     |
| `0px`             | ![](https://user-images.githubusercontent.com/7477678/235673876-34cc0f4d-e897-45e0-bd08-842086994b66.png) | ![](https://user-images.githubusercontent.com/7477678/235677265-f3858290-4469-4fa6-8497-6f95d4e3f013.png) | ![](https://user-images.githubusercontent.com/7477678/235678493-a7bffef0-7f72-4c4a-973f-e87d6c9f6468.png) | ![](https://user-images.githubusercontent.com/7477678/235680073-0cd52c3c-898e-425f-94e6-7831a9484b1e.png) |
| `-10px`           | ![](https://user-images.githubusercontent.com/7477678/235676468-c917d326-dfe8-4df8-a094-7f00c0e570c5.png) | ![](https://user-images.githubusercontent.com/7477678/235677395-970fca02-bfa6-499c-8e4e-8a9ea3ae0109.png) | ![](https://user-images.githubusercontent.com/7477678/235678950-dab0e6ec-00fc-4701-8308-3dcb9f7dcfba.png) | ![](https://user-images.githubusercontent.com/7477678/235680255-26b9cdc9-0cc9-4167-805a-95e6fb58bcf2.png) |
| `-20px`           | ![](https://user-images.githubusercontent.com/7477678/235674103-97591a1f-726d-4714-adfe-55c6a27d9a92.png) | ![](https://user-images.githubusercontent.com/7477678/235677557-10b93357-3a69-4b2d-afcf-280e23715431.png) | ![](https://user-images.githubusercontent.com/7477678/235679719-8b3767ed-a097-4594-a5b1-d48e397b06f9.png) | ![](https://user-images.githubusercontent.com/7477678/235680373-e0974772-d405-4c11-b6b2-90d68de09d82.png) |
| `-30px`           | ![](https://user-images.githubusercontent.com/7477678/235674887-3b2a076c-7872-4a3a-ac74-549f5ed8a8a5.png) | ![](https://user-images.githubusercontent.com/7477678/235677688-1b830065-2237-43ed-857e-e00c72217d91.png) | ![](https://user-images.githubusercontent.com/7477678/235679208-3c4b4e2f-62ea-4b9b-8aa7-1cb1d37d8e8a.png) | ![](https://user-images.githubusercontent.com/7477678/235680513-5514fe90-e8ff-433b-8e6f-588e0289e741.png) |
| `-40px`           | ![](https://user-images.githubusercontent.com/7477678/235675575-8086d655-cd4f-4074-bf09-740fc2506f68.png) | ![](https://user-images.githubusercontent.com/7477678/235677856-d92d9e31-cd7f-448e-9002-771d8edf6efd.png) | ![](https://user-images.githubusercontent.com/7477678/235679296-fe748d4a-d653-4ca4-b2ce-c9769fada75b.png) | ![](https://user-images.githubusercontent.com/7477678/235680585-860ca5d7-e2ab-44b1-b688-89c35d6af0e2.png) |
| `-50px`           | ?                                                                                                         | ![](https://user-images.githubusercontent.com/7477678/235678033-c929b776-9ad8-4ff5-b1a8-d2127d89e457.png) | ![](https://user-images.githubusercontent.com/7477678/235679416-5adb979b-2839-4c71-8685-9f7edf019d48.png) | ![](https://user-images.githubusercontent.com/7477678/235680688-550efda2-ec56-4477-ac87-93e50621c7de.png) |

I'm basing the "expected" column on https://drafts.csswg.org/css-backgrounds/#corner-shaping

> Note that if the center of a corner’s outer curve is past an opposite padding edge (in the border area of a side opposite the corner), the inner curve will not be a full quarter ellipse.
> ![](https://user-images.githubusercontent.com/7477678/235682228-02fa2ca8-e6bb-4b67-aa91-43862063b28d.png)
> Where the border-radius curve extends into the opposite sides' borders, the arc of the padding edge is less than 90°.

It also looks the best visually. It just has a problem when interacting with https://drafts.csswg.org/css-ui/#outline-offset

> Negative values must cause the outline to shrink into the border box. Both the height and the width of the outside of the shape drawn by the outline should not become smaller than twice the computed value of the [outline-width](https://drafts.csswg.org/css-ui/#propdef-outline-width) property to make sure that an outline can be rendered even with large negative values.

What is the "outside of the shape drawn by the outline"? Without `border-radius`, it's just the rectangle of the border area inflated by `outline-width` plus the used `outline-offset`. But with that definition it's not guaranteed that the outline can be rendered when using `border-radius`.

Above I used `border-radius: 100% 0 0 0` because I think it's clearer to understand, but the problem becomes worse with `border-radius: 100% 0`.

| `outline-offset`  | `0px`                                                                                                     | `-10px`                                                                                                   | `-20px`                                                                                                   | `-30px`                                                                                                   | `-40px` |
| :---:             | :---:                                                                                                     | :---:                                                                                                     | :---:                                                                                                     | :---:                                                                                                     | :---:   |
|                   | ![](https://user-images.githubusercontent.com/7477678/235685111-07c42d52-609d-400a-b4d1-35827acbf5ae.png) | ![](https://user-images.githubusercontent.com/7477678/235685176-11547b64-c555-496b-bdd7-bc9fe95461a0.png) | ![](https://user-images.githubusercontent.com/7477678/235685255-8b3ba8d5-6c83-4a51-aa19-e71c0cc72079.png) | ![](https://user-images.githubusercontent.com/7477678/235685339-a4143617-c195-4576-b054-0d8cc3d4f6c7.png) | ?       |

If my math is correct,
 - the cyan area inside the outline becomes 0 with `outline-offset: calc(100px*(1/sqrt(2)-1))`, aprox `-29.29px`.
 - the magenta area of the outline becomes 0 with `outline-offset: calc(100px*(1/sqrt(2)-1) - 10px)`, aprox `-39.29px`.
 - taken naively, the constraint allows down to `-50px`

I guess the solution is taking into account the impact of `border-radius` over the outline shape when computing the minimum `outline-offset`. But the math doesn't seem very easy in general when dealing with elliptical corners.

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


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

Received on Tuesday, 2 May 2023 15:38:43 UTC