Created attachment 433900 [details] Provided demo url loaded in Safari, code is on top, and an empty demo are on bottom Renders a blank looking (demo in an iframe): https://codepen.io/argyleink/pen/rNmzGzW Renders as expected (demo not in an iframe): https://codepen.io/argyleink/debug/rNmzGzW Can be mitigated by not using `color-scheme` or adjusting the values used to not include "dark".
We've got white text on white in the <iframe>. codepen styles the iframe background color to be white, and the default text color respects dark mode, so I think this is expected?
Created attachment 433957 [details] `html { background-color: Canvas; }` fix Here I set the background color of the document explicitly (though isn't this what it should be by default?), and then the iframe renders as expected. It seems like the iframe background color is taking precedence when the document clearly has a preference request with color-scheme?
iframe content background is transparent by default, and controlled by the enclosing page's style on the iframe. I don't think the UA can override that?
looks like there was resolution around this exact topic! https://github.com/w3c/csswg-drafts/issues/4772#issuecomment-591553929 here's a wpt https://wpt.fyi/results/?label=master&label=experimental&aligned&q=color-scheme-iframe-background-mismatch-alpha.html
Nice!
<rdar://problem/80922070>
Created attachment 436918 [details] Patch
This patch modifies the imported WPT tests. Please ensure that any changes on the tests (not coming from a WPT import) are exported to WPT. Please see https://trac.webkit.org/wiki/WPTExportProcess
Comment on attachment 436918 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=436918&action=review > Source/WebCore/rendering/RenderBoxModelObject.cpp:945 > + auto& frameView = view().frameView(); > + > + isOpaqueRoot = [&] { > + if (bgLayer.next() || bgColor.isOpaque()) > + return true; > + > + auto* ownerElement = document().ownerElement(); > + > + // Fill with a base color if we're the root document. > + if (!ownerElement) > + return !frameView.isTransparent(); > + > + if (ownerElement->hasTagName(frameTag)) > + return true; > + > + // Locate the <body> element using the DOM. This is easier than trying > + // to crawl around a render tree with potential :before/:after content and > + // anonymous blocks created by inline <body> tags etc. We can locate the <body> > + // render object very easily via the DOM. > + auto* body = document().bodyOrFrameset(); > + > + // SVG documents and XML documents with SVG root nodes are transparent. > + if (!body) > + return !document().hasSVGRootNode(); > + > + // Can't scroll a frameset document anyway. > + if (is<HTMLFrameSetElement>(*body)) > + return true; > + > + auto* frameRenderer = ownerElement->renderer(); > + if (!frameRenderer) > + return false; > + > + // iframes should fill with a base color if the used color scheme of the > + // element and the used color scheme of the embedded documentâs root > + // element do not match. > + if (frameView.useDarkAppearance() != frameRenderer->useDarkAppearance()) > + return !frameView.isTransparent(); > + > + return false; > + }(); > + > + frameView.setContentIsOpaque(isOpaqueRoot); Let's pull this root background paint into new function.
Created attachment 436937 [details] Patch
(In reply to Simon Fraser (smfr) from comment #9) > Comment on attachment 436918 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=436918&action=review > > > Source/WebCore/rendering/RenderBoxModelObject.cpp:945 > > + auto& frameView = view().frameView(); > > + > > + isOpaqueRoot = [&] { > > + if (bgLayer.next() || bgColor.isOpaque()) > > + return true; > > + > > + auto* ownerElement = document().ownerElement(); > > + > > + // Fill with a base color if we're the root document. > > + if (!ownerElement) > > + return !frameView.isTransparent(); > > + > > + if (ownerElement->hasTagName(frameTag)) > > + return true; > > + > > + // Locate the <body> element using the DOM. This is easier than trying > > + // to crawl around a render tree with potential :before/:after content and > > + // anonymous blocks created by inline <body> tags etc. We can locate the <body> > > + // render object very easily via the DOM. > > + auto* body = document().bodyOrFrameset(); > > + > > + // SVG documents and XML documents with SVG root nodes are transparent. > > + if (!body) > > + return !document().hasSVGRootNode(); > > + > > + // Can't scroll a frameset document anyway. > > + if (is<HTMLFrameSetElement>(*body)) > > + return true; > > + > > + auto* frameRenderer = ownerElement->renderer(); > > + if (!frameRenderer) > > + return false; > > + > > + // iframes should fill with a base color if the used color scheme of the > > + // element and the used color scheme of the embedded documentâs root > > + // element do not match. > > + if (frameView.useDarkAppearance() != frameRenderer->useDarkAppearance()) > > + return !frameView.isTransparent(); > > + > > + return false; > > + }(); > > + > > + frameView.setContentIsOpaque(isOpaqueRoot); > > Let's pull this root background paint into new function. Moved the majority of the logic into a new function in RenderView.
Comment on attachment 436937 [details] Patch Thanks for the review!
Committed r282020 (241325@main): <https://commits.webkit.org/241325@main> All reviewed patches have been landed. Closing bug and clearing flags on attachment 436937 [details].