You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[css-contain] content-visibility: auto and SVG-as-image #10347
Over in Mozilla bug 1894546, we got a report about something like an (invisible) SVG image rendering content-visibility: auto elements in Chromium but not Firefox / Safari.
Off-hand, I think per spec it is invalid. At least, I don't see how the viewport checks would run, since they run from the "update the rendering" steps in HTML.
I think that bug is invalid, but seems worth double-checking... @vmpstr do you know what's going on in Chromium? Should I file a Blink bug? Have I missed something that should make that work per spec?
Doesn't the SVG width and height define a viewport for content-visibility within that image?
This is essentially what Chromium does: anytime we paint an SVG, we set a "viewport" on it into which we paint and update all of its rendering as if that was the viewport (including intersection observer determination for c-v).
Hmm... does chromium run the whole lifecycle update for SVG images? That seems generally wasteful? Also, what if the image is out of view in the parent document? That'd behave inconsistently with <iframe> unless I'm missing something.
I believe Chromium does that yeah (@progers would know for sure). I suspect it's exactly to support cases like this. We're drawing this SVG into a canvas, and then using the pixels for some other reason. It's very disconnected from when we actually use the pixels and presumably we want to treat those pixels as if they were visible when painted.
content-visibility aside, Chromium does it also because of paint culling that we do for offscreen content. We basically want to ensure when we draw the SVG into a canvas in this way, the culling is not cutting off any paint.
Can you elaborate on the iframe inconsistency, I'm not sure I follow
does chromium run the whole lifecycle update for SVG images?
Chrome does run most of the steps for a full animation frame (see: SVGImage::PaintRecordForCurrentFrame), but steps like resize observer are no-ops. Chrome isn't calculating real user viewport intersection for images though, and is just treating the image contents as relevant to the user, regardless of whether the image is on screen.
Offscreen content brought on-screen via a filter is considered relevant to the user (spec). I think ctx.drawImage should work similarly.
A content-visibility: auto element in an iframe will, IIRC use an IntersectionObserver-like check to intersect with the top level viewport. But that doesn't work if your image can be painted in multiple places and the data is shared.
IIUC, the content would be "relevant" in both images regardless. While if they were iframes, the content will be relevant in the top iframe, but not in the bottom.
So I think that, effectively for this purpose at least, you just ignore content-visibility: auto (everything is relevant in an SVG image, kind of)
Chrome does this as well. We need to pass in some context-specific data when drawing the image, such as when two <img>s reference the same svg but have different sizes (code). It would be technically possible to include top-level viewport intersection in this context-specific data.
There are are some spec'd differences between svgs in iframes vs svg images, such as how svg image do not allow interaction or script (secure animated mode). Because of the restrictions of svg images, there is almost no observable difference if we just consider them as always relevant to the user vs actually calculating top-level-viewport intersection.
After the initial, synchronous, viewport-proximity check in update-the-rendering (checkForInitialDetermination), subsequent viewport-proximity is updated in the next rendering opportunity, and so is one frame late. Animations in svg could be used with this one-frame-late aspect to show a user-visible difference between svg-iframe and svg-image content-visibility behavior. Because of this, and ctx.drawImage, I think it would be useful to specify whether svg-as-image is always relevant to the user (I am in favor).
I am also surprised about this case -- it took a big of digging to figure out what Blink was doing. I also support making svg-as-image cases always relevant
The CSS Working Group just discussed [css-contain] content-visibility: auto and SVG-as-image, and agreed to the following:
RESOLVED: treat content-visibility:auto as visible inside of SVG Image documents
RESOLVED: when printing a document, also treat content-visibility:auto as visible
The full IRC log of that discussion
<TabAtkins> emilio: someone was using <foreignObject> inside of svg-as-image with content-visibility:auto on it
<TabAtkins> emilio: spec isn't super clear... c-v:auto determination happens on the html rendering loop
<TabAtkins> emilio: not clear when and how that happens for svg images
<TabAtkins> emilio: for gecko and webkit it doesn't seem to happen in the rendering loop
<TabAtkins> emilio: so in gecko/webkit, c-v:auto remains hidden
<TabAtkins> emilio: It also isn't clear what that would mean for svg images actually attached ot the document
<TabAtkins> emilio: like using canvas
<TabAtkins> emilio: I think the simplest fix is to say that c-v:auto behaves as visible on svg images
<TabAtkins> emilio: they're generally not dynamic anyway, you can't run script
<TabAtkins> emilio: so I think that's a simple answer to the question, trivially implementable. and aligns with chrome.
<TabAtkins> emilio: so proposal to treat c-v:auto as visible in SVG Image documents
<TabAtkins> TabAtkins: the html rendering loop handles inline svg, right?
<TabAtkins> emilio: Yes, and iframes. just not svg images.
<vmpstr> +1 to the proposal
<TabAtkins> astearns: questions or concerns?
<TabAtkins> astearns: objections to the proposal?
<ydaniv> +1
<emilio> q+
<TabAtkins> RESOLVED: treat content-visibility:auto as visible inside of SVG Image documents
<TabAtkins> emilio: another thing i just thought of, similar issue with lazy-loaded images
<TabAtkins> emilio: long-standing issue across engines
<TabAtkins> emilio: what to do about printing of lazy-loaded images
<TabAtkins> emilio: should we do the same for printing? un-hide them?
<TabAtkins> emilio: you could argue that for c-v:auto you should treat it as visible
<TabAtkins> emilio: might be worth discussing in a separate issue
<TabAtkins> emilio: Printing is just another palce that doesn't go thru the normal rendering loop
<fantasai> /win 15
<bramus> TabAtkins: in a meaningful sense you print a viewport sized to the entire document spread across pages
<fantasai> s|/win 15//
<bramus> … for purpose of cv auto I agree with you
<fantasai> s|/win 15||
<TabAtkins> emilio: I'm happy to propose that, or we can take it to another issue
<TabAtkins> astearns: so if printing is defined as printing in a large viewport
<TabAtkins> astearns: isn't it already defined?
<bramus> TabAtkins: its not actually defined that way. The viewport while printing is page based. For prupose of cv auto its as is full document is in viewport
<TabAtkins> astearns: So does anyone have objections to resolving on this?
<emilio> ack emilio
<TabAtkins> RESOLVED: when printing a document, also treat content-visibility:auto as visible
Activity
vmpstr commentedon May 21, 2024
Doesn't the SVG width and height define a viewport for
content-visibilitywithin that image?This is essentially what Chromium does: anytime we paint an SVG, we set a "viewport" on it into which we paint and update all of its rendering as if that was the viewport (including intersection observer determination for c-v).
/cc @progers
emilio commentedon May 21, 2024
Hmm... does chromium run the whole lifecycle update for SVG images? That seems generally wasteful? Also, what if the image is out of view in the parent document? That'd behave inconsistently with
<iframe>unless I'm missing something.vmpstr commentedon May 22, 2024
I believe Chromium does that yeah (@progers would know for sure). I suspect it's exactly to support cases like this. We're drawing this SVG into a canvas, and then using the pixels for some other reason. It's very disconnected from when we actually use the pixels and presumably we want to treat those pixels as if they were visible when painted.
content-visibilityaside, Chromium does it also because of paint culling that we do for offscreen content. We basically want to ensure when we draw the SVG into a canvas in this way, the culling is not cutting off any paint.Can you elaborate on the iframe inconsistency, I'm not sure I follow
progers commentedon May 22, 2024
Chrome does run most of the steps for a full animation frame (see: SVGImage::PaintRecordForCurrentFrame), but steps like resize observer are no-ops. Chrome isn't calculating real user viewport intersection for images though, and is just treating the image contents as relevant to the user, regardless of whether the image is on screen.
Offscreen content brought on-screen via a filter is considered relevant to the user (spec). I think
ctx.drawImageshould work similarly.emilio commentedon May 22, 2024
I mean, at least Gecko shares SVG-as-images.
A
content-visibility: autoelement in an iframe will, IIRC use anIntersectionObserver-like check to intersect with the top level viewport. But that doesn't work if your image can be painted in multiple places and the data is shared.Consider:
IIUC, the content would be "relevant" in both images regardless. While if they were iframes, the content will be relevant in the top iframe, but not in the bottom.
So I think that, effectively for this purpose at least, you just ignore
content-visibility: auto(everything is relevant in an SVG image, kind of)progers commentedon May 22, 2024
Chrome does this as well. We need to pass in some context-specific data when drawing the image, such as when two
<img>s reference the same svg but have different sizes (code). It would be technically possible to include top-level viewport intersection in this context-specific data.There are are some spec'd differences between svgs in iframes vs svg images, such as how svg image do not allow interaction or script (secure animated mode). Because of the restrictions of svg images, there is almost no observable difference if we just consider them as always relevant to the user vs actually calculating top-level-viewport intersection.
progers commentedon May 22, 2024
After the initial, synchronous, viewport-proximity check in update-the-rendering (checkForInitialDetermination), subsequent viewport-proximity is updated in the next rendering opportunity, and so is one frame late. Animations in svg could be used with this one-frame-late aspect to show a user-visible difference between svg-iframe and svg-image content-visibility behavior. Because of this, and
ctx.drawImage, I think it would be useful to specify whether svg-as-image is always relevant to the user (I am in favor).emilio commentedon May 22, 2024
That seems reasonable. Honestly I am a bit surprised about this use case as a whole, but that is trivial to implement and easy to test too.
vmpstr commentedon May 22, 2024
I am also surprised about this case -- it took a big of digging to figure out what Blink was doing. I also support making svg-as-image cases always relevant
css-meeting-bot commentedon Jun 13, 2024
The CSS Working Group just discussed
[css-contain] content-visibility: auto and SVG-as-image, and agreed to the following:RESOLVED: treat content-visibility:auto as visible inside of SVG Image documentsRESOLVED: when printing a document, also treat content-visibility:auto as visibleThe full IRC log of that discussion
<TabAtkins> emilio: someone was using <foreignObject> inside of svg-as-image with content-visibility:auto on it<TabAtkins> emilio: spec isn't super clear... c-v:auto determination happens on the html rendering loop
<TabAtkins> emilio: not clear when and how that happens for svg images
<TabAtkins> emilio: for gecko and webkit it doesn't seem to happen in the rendering loop
<TabAtkins> emilio: so in gecko/webkit, c-v:auto remains hidden
<TabAtkins> emilio: It also isn't clear what that would mean for svg images actually attached ot the document
<TabAtkins> emilio: like using canvas
<TabAtkins> emilio: I think the simplest fix is to say that c-v:auto behaves as visible on svg images
<TabAtkins> emilio: they're generally not dynamic anyway, you can't run script
<TabAtkins> emilio: so I think that's a simple answer to the question, trivially implementable. and aligns with chrome.
<TabAtkins> emilio: so proposal to treat c-v:auto as visible in SVG Image documents
<TabAtkins> TabAtkins: the html rendering loop handles inline svg, right?
<TabAtkins> emilio: Yes, and iframes. just not svg images.
<vmpstr> +1 to the proposal
<TabAtkins> astearns: questions or concerns?
<TabAtkins> astearns: objections to the proposal?
<ydaniv> +1
<emilio> q+
<TabAtkins> RESOLVED: treat content-visibility:auto as visible inside of SVG Image documents
<TabAtkins> emilio: another thing i just thought of, similar issue with lazy-loaded images
<TabAtkins> emilio: long-standing issue across engines
<TabAtkins> emilio: what to do about printing of lazy-loaded images
<TabAtkins> emilio: should we do the same for printing? un-hide them?
<TabAtkins> emilio: you could argue that for c-v:auto you should treat it as visible
<TabAtkins> emilio: might be worth discussing in a separate issue
<TabAtkins> emilio: Printing is just another palce that doesn't go thru the normal rendering loop
<fantasai> /win 15
<bramus> TabAtkins: in a meaningful sense you print a viewport sized to the entire document spread across pages
<fantasai> s|/win 15//
<bramus> … for purpose of cv auto I agree with you
<fantasai> s|/win 15||
<TabAtkins> emilio: I'm happy to propose that, or we can take it to another issue
<TabAtkins> astearns: so if printing is defined as printing in a large viewport
<TabAtkins> astearns: isn't it already defined?
<bramus> TabAtkins: its not actually defined that way. The viewport while printing is page based. For prupose of cv auto its as is full document is in viewport
<TabAtkins> astearns: So does anyone have objections to resolving on this?
<emilio> ack emilio
<TabAtkins> RESOLVED: when printing a document, also treat content-visibility:auto as visible