Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-masking?] "object bounding box" needs to be better defined for CSS boxes #5786

Open
smfr opened this issue Dec 12, 2020 · 10 comments
Open

Comments

@smfr
Copy link
Contributor

smfr commented Dec 12, 2020

CSS masking https://drafts.fxtf.org/css-masking-1/#valdef-clip-path-fill-box references the "object bounding box" which is used when computing the geometry of a clip-path to apply to a CSS box.

SVG https://svgwg.org/svg2-draft/coords.html#TermObjectBoundingBox defines the bounding box as " the tightest fitting rectangle aligned with the axes of that element's user coordinate system that entirely encloses it and its descendants." but for CSS this needs a tighter definition; it needs to specify whether that includes ink overflow (e.g. box-shadow), outlines, and how it interacts with overflow:hidden on the element.

There is a lack of browser interop here: https://codepen.io/smfr/pen/jOMyVLO

yury-s pushed a commit to yury-s/webkit-http that referenced this issue Dec 15, 2020
…tains transformed child

https://bugs.webkit.org/show_bug.cgi?id=219829
Source/WebCore:

<rdar://problem/66308088>

Reviewed by Said Abou-Hallawa.

When computing the geometry for clip-path when applied to a CSS box, we should take overflow:hidden
on the box into account. It's not entirely clear what the correct geometry is
(w3c/csswg-drafts#5786) but this avoids stretched masks.

Test: css3/masking/clip-path-overflow-hidden-bounds.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::setupClipPath):

LayoutTests:

Reviewed by Said Abou-Hallawa.

* css3/masking/clip-path-overflow-hidden-bounds-expected.html: Added.
* css3/masking/clip-path-overflow-hidden-bounds.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@270850 268f45cc-cd09-0410-ab3c-d52691b4dbfc
ryanhaddad pushed a commit to WebKit/WebKit that referenced this issue Dec 22, 2020
…tains transformed child

https://bugs.webkit.org/show_bug.cgi?id=219829
Source/WebCore:

<rdar://problem/66308088>

Reviewed by Said Abou-Hallawa.

When computing the geometry for clip-path when applied to a CSS box, we should take overflow:hidden
on the box into account. It's not entirely clear what the correct geometry is
(w3c/csswg-drafts#5786) but this avoids stretched masks.

Test: css3/masking/clip-path-overflow-hidden-bounds.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::setupClipPath):

LayoutTests:

Reviewed by Said Abou-Hallawa.

* css3/masking/clip-path-overflow-hidden-bounds-expected.html: Added.
* css3/masking/clip-path-overflow-hidden-bounds.html: Added.

Canonical link: https://commits.webkit.org/232491@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@270850 268f45cc-cd09-0410-ab3c-d52691b4dbfc
@smfr smfr added the Agenda+ label Oct 16, 2021
@smfr
Copy link
Contributor Author

smfr commented Oct 16, 2021

For transform-box and the geometry box argument to clip-path, fill-box maps to object bounding box for SVG elements. For CSS boxes, fill-box maps to the content box, which makes me think that "object bounding box" should map to the content box. However, browsers seem to map to the border box.

Simpler example: https://codepen.io/smfr/pen/yLoebgw

@smfr
Copy link
Contributor Author

smfr commented Oct 16, 2021

To clarify, this matters when the clip path has clipPathUnits="objectBoundingBox".

@smfr
Copy link
Contributor Author

smfr commented Oct 18, 2021

See also #6383

@svgeesus
Copy link
Contributor

" the tightest fitting rectangle aligned with the axes of that element's user coordinate system that entirely encloses it and its descendants." but for CSS this needs a tighter definition; it needs to specify whether that includes ink overflow (e.g. box-shadow), outlines, and how it interacts with overflow:hidden on the element.

The text in SVG2 could usefully be tightened up, but from memory of discussions many years ago, the SVG bounding box is the bound of the geometry. This means that it specifically excludes:

  • the stroke, including the big excursions that can occur when the miter limit is poorly chosen on acute angles
  • markers

There has in the past been discussion to define another bounding box, ink-based rather than geometric, which would include those items. There is clearly a need for both boxes.

To my mind, that means that for CSS, stroking and ink overflow should not be included. Or, again, that both options should be available.

@smfr
Copy link
Contributor Author

smfr commented Oct 19, 2021

There are two aspects to this, for a simple box, what is the geometry. Then, for a box with descendants that are outside its bounds, what is the geometry. My testcase for this has a position:absolute div with a position:absolute child that is partially outside the first box.

@w3c w3c deleted a comment from css-meeting-bot Nov 3, 2021
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed "object bounding box" needs to be better defined for CSS boxes.

The full IRC log of that discussion <dholbert> topic: "object bounding box" needs to be better defined for CSS boxes
<dholbert> smfr: this is about css & svg
<dholbert> smfr: you can apply clip-path to an element
<astearns> github: https://github.com//issues/5786
<dholbert> smfr: you can use clip-path-units: object-bounding-box
<dholbert> smfr: in the testcase I was playing with, the element w/ clip-path was an abspos element with a positioned descendant sticking out of its bounds
<dholbert> smfr: the question is, what's the bounding box
<dholbert> smfr: letter of the svg spec says: traverse the element and whole descendant tree, compute a bounding box that encloses them all
<dholbert> smfr: but that seems a little crazy & isn't what 2 of the browsers do
<astearns> ack fantasai
<dholbert> fantasai: first thought: ink-overflow is theoretically infinite. so if we're doing a geometric operation where author needs to rely on a particular area of the screen, then we can't be dependent on ink-overflow
<dholbert> smfr: agree
<dholbert> smfr: if one of those descendant elements moves around, do you want to adjust clip path on every frame of animation?
<dholbert> TabAtkins: we have a definition of how this applies to CSS boxes elsewhere. Is that sufficient?
<dholbert> smfr: I would be fine if we said object bounding box matched one of those boxes, e.g. border-box
<dholbert> smfr: [...] that's what two of the browsers implement
<dholbert> smfr: I think chrome includes all the descendants
<dholbert> chrishtr: ok
<TabAtkins> https://drafts.fxtf.org/fill-stroke/#fill-origin
<dholbert> TabAtkins: looking for where this was defined
<dholbert> TabAtkins: I see the css-to-svg keyword mapping in draft fill-stroke spec
<dholbert> chrishtr: this demo from the issue, is that the one where Chrome behaves differently?
<dholbert> smfr: look at the codepen in second comment there
<fantasai> TabAtkins, https://www.w3.org/TR/css-box-3/#keywords ?
<TabAtkins> ah yes, that's it
<dholbert> astearns: chrishtr, do you need a little more time to look at this?
<dholbert> chrishtr: yeah, need to research the code. smfr's proposal sounded good but it surprises me that Chrome doesn't implement it
<astearns> ack fantasai
<dholbert> fantasai: the keyword mapping is in the box model spec
<fantasai> https://www.w3.org/TR/css-box-3/#keywords
<dholbert> fantasai: [describes box mapping]
<dholbert> smfr: problem there, object-bounding-box is mapped to fill-box, but that doesn't include borders, which doesn't match what browsers do
<dholbert> fantasai: if that's what browsers are doing then we should update the mapping
<dholbert> heycam: that makes it inconsistent with what SVG is doing, where object-bounding-box is defined to do the same thing as getBBox, which is the geometry of the shape excluding stroke
<dholbert> chrishtr: (describes observations of example)
<dholbert> smfr: if you compare Chrome to other engines, it looks different; I'm not entirely sure what rectangle Chrome is using
<dholbert> chrishtr: it would be great to take this offline and circle back next week, so I can find out what Chrome is doing. I'll comment on the issue soon
<dholbert> smfr: do we need to separately resolve the "object-bounding-box is fill-box" ambiguity
<dholbert> smfr: I think it needs more research
<dholbert> smfr: we need to find places that reference object-bounding-box in css specs and see if those should map to fill-box or border-box
<dholbert> astearns: separate issue would be good
<dholbert> smfr: I'll file
<dholbert> astearns: resolution that we'd like to take up for this one is that bounding-box for SVG masking should be the border-box?
<dholbert> chrishtr: that's what we'd like to aim for, after research
<dholbert> astearns: let's see if we can resolve on that next week or week after
<dholbert> astearns: break!
<dholbert> astearns: resume at 5 after the hour

@chrishtr
Copy link
Contributor

chrishtr commented Nov 3, 2021

I tested with Firefox for this example: https://codepen.io/smfr/pen/yLoebgw

Firefox's clip depends on the child's size and position, leading me to conclude that browser is, at least in this case, including descendants' bounds as an input to "objectBoundingBox".

Chrome does not.

I think Chrome's behavior is better because it is simpler and more performant.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Object Bounding Box.

The full IRC log of that discussion <fantasai> Topic: Object Bounding Box
<fantasai> github: https://github.com//issues/5786
<fantasai> astearns: conclusion from IRC conversation?
<fantasai> chrishtr: Chrome uses just the border box of the element only
<fantasai> chrishtr: Firefox includes descendants
<fantasai> chrishtr: So Chrome seems to implement what we want, which is to use border box and not bounding box of descendants
<fantasai> smfr: This resolution would affect Gecko; WebKit already matches
<fantasai> dholbert: Unsure what we're doing exactly, but proposal sounds pretty reasonable
<fantasai> astearns: So proposed resolution is to use the border-box for masking in SVG?
<TabAtkins> fantasai: Is this changing the interpretation fo the fill-box keyword? Or just the interpretation of what we do by default, and in what properties?
<fantasai> chrishtr: I think it's changing interpretation of "object bounding box" for clip-path
<chrishtr> clipPathUnits="objectBoundingBox"
<fantasai> astearns: Is there a way to change to use something other than object bounding box?
<fantasai> astearns: Is that only the default behavior or ...?
<fantasai> smfr: fantasai's point is valid, we need to resolve ambiguities between when object bounding box is applied to CSS
<fantasai> smfr: problem with fill-box and border-box being different
<fantasai> chrishtr: can specify various boxes
<fantasai> iank_: Also bug/ambiguity, when fragmented
<fantasai> iank_: need to clarify applying to each fragment independently
<fantasai> astearns: Proposed resolution as stated is not everything we need to fix?
<TabAtkins> fantasai: I think the fill-box keyword is mapped ot the OBB, and also to the content box
<TabAtkins> fantasai: So does that change, when fill-box is specified explicitly?
<TabAtkins> fantasai: If it does get redefined, do we do so only for clip-path or for all places?
<TabAtkins> fantasai: So we need to dig in and see if we were onlya ffecting clip-path:<initial-value>, clip-path:fill-box, or <any-property>:fill-box
<fantasai> heycam: for clip-path object bounding box, no way to switch to another box
<fantasai> heycam: so if we are changing definition of 'fill-box', would need to consider in other contexts
<fantasai> heycam: but at the moment, I don't think there's a way to explicitly select any of the other boxes
<fantasai> astearns: There is in CSS, but maybe not in SVG
<fantasai> heycam: I don't think those would affect how SVG clip path would be positioned
<fantasai> astearns: Do we have a simple resolution and then action to audit?
<fantasai> chrishtr: Let's resolve, and then ask editors to audit and come back to group
<fantasai> astearns: sgtm
<fantasai> astearns: what's the proposed resolution?
<fantasai> chrishtr: If you set 'clip-path' to use object bounding box units in an SVG-based clip-path, it refers to bounding box of the element to which clip is applied
<fantasai> chrishtr: border box
<fantasai> proposed resolution: SVG clip-path bounding box units refer to CSS border-box of element to which applied
<fantasai> RESOLVE: SVG clip-path bounding box units refer to CSS border-box of element to which applied
<fantasai> s/RESOLVE/RESOLVED/
<fantasai> ACTION: Editors to check if any other related amiguities

@chrishtr
Copy link
Contributor

chrishtr commented Nov 3, 2021

Resolved: SVG clip-path objectBoundingBox units refer to CSS border-box of element to which applied.

@astearns astearns removed the Agenda+ label Nov 3, 2021
@smfr
Copy link
Contributor Author

smfr commented Nov 4, 2021

I filed #6796 on the object bounding box/fill-box ambiguity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants