-
Notifications
You must be signed in to change notification settings - Fork 669
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-images-4] Proposal to allow replaced elements to paint outside of their bounds #7058
Comments
I think this would work for both the overflowing pixels and pixels that are clipped to be smaller than the element box (e.g. with clip-path), since that allows us to capture just the bounds of the actual visible pixels and then use object-view-box to position them appropriately. One question: presumably this has no direct interaction with something like witdth/height changes but is affected by transform changes, right? If we create an animation to change the width, we would have to create an animation to also change the object-view-box properties to change in tandem so that it looks like the element is shrinking and its drop shadow (for e.g) is changing shape but is remaining relative to the bottom right of the new element I think that's fine, but if we can have some sort of a syntactic sugar to help, it would be awesome. Thinking out-loud: I'm thinking something like if we had object-intrinsic-size and object-view-box where the object-intrinsic-size would specify how big the replaced element naturally is and object-view-box is what you said (except that it only affects the pixel content size not the.. natural size (i fully appreciate that we might need new terminology)). Then if you do a width animation, you would note that the object-intrinsic-size doesn't match the element size anymore, and you can figure out exactly how to scale the object-intrinsic-size to make the two rects align. Then you apply that same scale to the object-view-box which should scale the pixel contents in the same way as the width animation is changing the element Let me know if any of that makes sense and what your thoughts are |
SVG has been on a quest to map all its attributes to CSS properties, why not map this to the viewbox attribute? |
I probably misunderstood the proposal, since I think the width/height changes will naturally change the object, by scaling its natural dimensions (subject to object-fit). |
The idea looks good. I want to reiterate to make sure I understand it correctly and also clarify how this interacts with existing sizing/positioning options of object-fit and object-position. So for example if we have an element sized 100X200 with a 10px shadow on all edges, it's snapshot's intrinsic size is 120X220. We'd render this in a replaced element sized to 100X200 (which provides the specified size) with object-view-box: 10,10,100,200. The natural size used by the replaced element's sizing algorithm is then 100X200 and the paint content is the subset specified using object-view-box. What happens when this image is rendered in a replaced element of specified size of 100X100 with object-fit: contain and object-position: left top? I'm assuming we'd downscale the complete image to 50X100. So now point (5,5) in the downscaled image will map to the origin of the replaced element's content-box. |
Correct.
Correct; that's still the edge of the element-box part of the image, with the shadow outside of that point. The view-box shifting/stretching happens before any of the other object-* adjustments. |
You mean if you're animating the source element providing the image snapshot? Yes, you'd have to align the object-view-box on the pseudo-element hosting the snapshot to match it. If we wanted sugar, we could invent a new "natural view-box" term (which all existing images wouldn't have), and let the snapshotting process produce an image with the natural view-box set appropriately to match the element dimensions; then we can have an |
I meant to say that the downscaled image would be 60X110 in this case with a 5px shadow around it. But I think you got it. :) I'm also assuming that object-view-box should be a strict subset of the image's intrinsic size, since it's meant to be a subset of the image's pixels. So x/y can't have any negative values and x+width/y+height is capped to its intrinsic width/height? |
The CSS Working Group just discussed
The full IRC log of that discussion<dael> Topic: [css-images-4] Proposal to allow replaced elements to paint outside of their bounds<dael> github: https://github.com//issues/7058 <fantasai> s/current behavior/current syntax <dael> TabAtkins: While discussing the shared element transitions proposal a couple weeks ago there was some obvious need to control how the image snashot sized better <dael> TabAtkins: The image snapshot can be size to elements but larger to capture outlines or shadows. Awk interaction with normal image sizing. When looking at Jake prop I realized this would be useful in general and addresses a gap in Paint API <dael> TabAtkins: General is add 2 prop to object family; object-viewbox and object-overflow. Apply a iewbox to replaced content and allow it to overflow context box <dael> TabAtkins: Viewbox is same grammer as svg and has same effect. Let's you say x/y boundary is the image boundary. <dael> TabAtkins: [gives example] <dael> TabAtkins: The natural size of image adjusts to spec width and height. For sizing it assumes the elemnt transition snapshot is the size of element border box. If part outside is displayed somehow due to something like object-overflow you can see the rest like the shadows <dael> TabAtkins: Generalizing the use case, one of the use cases we wanted to handle in Houdini is doing custom shadows. Groups like google material design did optics based shadowing. b/c couldn't paint outside hte bounds you had to do weird tricks to do it <dael> TabAtkins: This would allow you to do that exact thing as well when paired with object-overflow. 2 properties, hidden and visible. hidden is like today <dael> TabAtkins: With these 2 properties would help a lot with shared element transitions but useful general property <dael> TabAtkins: fantasai provided feedback might be good to have it just be viewport and we upgrade the svg to a property and do that. <Rossen_> q? <smfr> q+ <dael> TabAtkins: I'm fine with that if people believe it's a good way to go <dael> TabAtkins: Last I checked no other feedback. Any quesitons or concerns I'd love to hear it. <dael> TabAtkins: Else could add to images <Rossen_> ack smfr <dael> smfr: Sounds reasonable. Not a huge fan of new ways to do ink overflow, but I see the use case <dael> smfr: If you do object overflow and then object-fit:cover you'll have bits outside that don't respond to hit testing. Might enocourage people to make weird content for hit testing <plinss> q+ <dael> TabAtkins: That is true. I don't know how to address it, though. It's part of core functionality since shadows shouldn't hit, but you could also do cover. Not sure if we can slve that or put a note saying don't do <dael> smfr: Note is prob fine <dael> smfr: Other thought is how it interacts with a-r <Rossen_> q? <dael> TabAtkins: Should be straightfoward. Changes element natural size to spec width and height and that implies a-r. I'm not sure if we allow width and height w/o a-r. Should have same effect. 2:1 and set square viewbox it's 1:1 for all other purposes <dael> smfr: Alright <Rossen_> ack plinss <dael> plinss: I thought I heard there would be viewbox property that takes same as svg viewbox? <dholbert> q+ <dael> plinss: Little concerned b/c svg will look a bit like standard rect and it's not. Might be confusing. Maybe have it be a shape function? <dael> TabAtkins: Would that imply we want to allow other shape or is this just special for the property? <dael> plinss: Restrict to small set of shapes. rect and inset might make sense. <dael> plinss: Just confusing about a bare property that takes 4 values but it's not the same <fantasai> +1 to plinss's suggestion of both rect() and inset() <dael> TabAtkins: I get you. And having rect and inset would be pretty worthwhile. If you use viewbox you have to get width and height but inset lets you set 20px. I think that sounds pretty good <dael> plinss: I'm not opposed to having another one to take svg syntax for people who know it but we should call out <dael> TabAtkins: Doesn't rest take svg? <dael> plinss: I think it's trbl <dholbert> s/rest/rect/ <dael> s/rest/rect <dael> plinss: I don't want to rat hole, but calling out <dael> TabAtkins: We don't have rect, we have inset. So add a rec or some other name that takes xy stuff <fantasai> xywh <vmpstr> q+ <dael> plinss: There is rect on clip unfortunately <fantasai> xywh() <dael> TabAtkins: Okay <Rossen_> ack dholbert <dael> dholbert: One other concern with svg viewbox is it's a list of 4 numbers and doesn't allow units or %. Might make it we'd have to extend a fair bit. Might be worth abandoning it for that purpose <dael> TabAtkins: I would have presumed we upgrade to css units. But point taken <Rossen_> ack vmpstr <dael> vmpstr: I wanted to confirm how scaling works. If we scale images such that we squish. Squish the viewbox and overflow squishes <dael> TabAtkins: Right. If you scale image of svg element using viewbox the whole thing squishes including the outside <dael> fantasai: For rect function media uses xywh. Makes it clear what each argument would be. <dael> fantasai: For svg correspondence we've tried to create mappings. We should look more b/c if we can make them map it solves viewbox which has not had a mapping <dael> TabAtkins: I don't think there is a big problem...speaking from ignorance but suspect not a big problem with making this property override viewbox of inline svg. Probably okay. <dael> TabAtkins: Should put in as an issue without effecting rest of design <dael> fantasai: If you put it in from an embedded svg it should have same effect <dael> TabAtkins: not sure about that. That would mean that applying the style to an image element could have distinct effects based ono source type <dael> fantasai: True for width and height. If you apply sizing to root svg for embedded vs inline get different <dael> TabAtkins: Talking embedded svg vs png <dael> fantasai: No, if you have it inside the svg file <Rossen_> q? <Rossen_> ack fantasai <dael> TabAtkins: Yes, yes. If it applies to svg and html it would apply to raw svg as well <TabAtkins> s/svg and html/svg-in-html/ <dael> fantasai: Sounds like prop is we have these 2 properties, object-viewbox and object-overflow. 1 is bool about hidden and visible and the other is eq. of SVG viewbox. We would try and create a mapping between svg and new property. New property would take inset and xywh so there's 2 ways to spec size <dael> fantasai: And that's in images 5 <dael> TabAtkins: Correct <dael> Rossen_: Other opinions? <dael> Rossen_: Objections? <dael> RESOLVED: We add to Images 5 these 2 properties, object-viewbox and object-overflow. 1 is bool about hidden and visible and the other is eq. of SVG viewbox. We would try and create a mapping between svg and new property. New property would take inset and xywh so there's 2 ways to spec size |
If the viewBox-like property here does indeed end up being an alias / override for the SVG viewBox attribute, then a few things to consider...
|
The `<basic-shape-rect>` construct introduced in w3c#7058 needs to be wrapped in another pair of `<>`, otherwise it gets interpreted as an unknown custom markup tag and property value gets rendered as: `none |`.
@tabatkins The WG resolution said to add this to CSS Images L5, not L4. And it was said to map it to the SVG viewbox attribute, not make it similar but different. Please try to pay more attention to what you're supposed to be editing when making edits? :( |
Context: WICG/view-transitions#120, where we want to snapshot an element as an image, paint it into a box of the right size, but also get the "decorations" (borders, outlines, shadows) painted outside of that box.
This seems like a useful functionality more generally, as well; in some cases you can use border-image to make an image paint "outside of" an element, but the painting area still takes up layout space (you inset from the edge of the border area, but can't go outside of it). This can allow an author to, for example, create an image with a custom glow or shadow applied, with proper ink-overflow behavior like a CSS shadow would have.
I propose we do this with two new
object-*
properties:object-view-box
takes an x/y/width/height quartet of lengths, and has two effects:hidden
, the replaced content is clipped to the element's content box.visible
, the replaced content can overflow the element's content-box. This overflowing content is counted as ink overflow. (To overflow, at least one of the otherobject-*
properties must be in use.)So for the use-case in the linked issue, we'd set the w/h part of object-view-box to the size of the snapshotted element, and x/y according to the amount of snapshot margin captured around it (to get shadows/etc), and set
object-overflow: visible
to let those shadow ink-overflow properly. If we then let the element size per its natural size, it will correctly take on the size of the snappshotted border box exactly, which is precisely what we want.Thoughts? Concerns? Other possible directions?
/cc @chrishtr @jakearchibald @khushalsagar
The text was updated successfully, but these errors were encountered: