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-color-adjust-1] color-scheme should affect embedded iframes #4772

Closed
tomayac opened this issue Feb 13, 2020 · 22 comments
Closed

[css-color-adjust-1] color-scheme should affect embedded iframes #4772

tomayac opened this issue Feb 13, 2020 · 22 comments

Comments

@tomayac
Copy link
Contributor

tomayac commented Feb 13, 2020

When a site contains iframes that specify their color-scheme either via the meta tag or the CSS property, the default text color changes, however, the background color is transparent, see this demo and note how the screenshot (Chrome Canary 82 left, Safari Tech Preview 100 right) shows the disappearing heading (white on white):

Screen Shot 2020-02-12 at 10 15 16

(Chrome doesn't implement form element darkening yet.)

If, however, one loads one of the embedded iframes in isolation (demo), things work as expected and the background is dark (again Chrome left, Safari right):

Screen Shot 2020-02-13 at 08 56 20

As discussed with @chrishtr in an offline thread, color-scheme should arguably also affect embedded iframes and render them as if they were the root document.

Spec links:

CC: @lilles

@lilles lilles added the css-color-adjust-1 Current Work label Feb 14, 2020
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-color-adjust-1] `color-scheme` should affect embedded iframes.

The full IRC log of that discussion <dael> Topic: [css-color-adjust-1] `color-scheme` should affect embedded iframes
<dael> github: https://github.com//issues/4772
<dael> fantasai: Has normal and other values like darka nd light. Since iFram has change parent and it has different color scheme then main page you can't see iFrame content. Raised that non-normal should cause iFrame to have opaque BG
<dael> fantasai: Whatever webpage is in that frame assumes a different bg then has on own
<dael> chrishtr: and iFrame could override it
<dael> fantasai: iFrame can't choose transparent if we make not transparent, right? Original is transparent and canvas is color
<dael> chrishtr: Canvas behind html element should be opaque
<dael> fantasai: I think
<dael> chrishtr: bg of html element?
<dael> fantasai: Have to change computed of bg color property. initial value is transparent
<dael> chrishtr: I thought for root going to dark theme cause bg of root to change in ua stylesheet. no?
<dael> fantasai: I think it's defined as canvas changes. Could change definition
<dael> chrishtr: Maybe needs more research
<dael> fantasai: kay
<dael> astearns: Research on whats overwritten?
<dael> chrishtr: Yeah. Need to make so dev overwrite it. need to research what spec says
<fantasai> https://drafts.csswg.org/css-color-adjust-1/#preferred
<dael> astearns: Okay, will leave be. I'll remove agenda tag. Once there's a prop please add the tag back

@astearns astearns removed the Agenda+ label Feb 19, 2020
@lilles
Copy link
Member

lilles commented Feb 20, 2020

If we introduce this on the root element instead of the canvas you would also have the question of whether it should be solid white, instead of transparent, for the light color-scheme. That would not be web-compatible.

You have the same issue, without color-scheme, embedding an unstyled document in a top document with a black background:

<!doctype html>
<body style="background:black;color:white">
<p>Do you see the iframe text?</p>
<iframe src="data:text/html,iframe text"></iframe>

If the root element got a solid dark background here, and you wanted a transparent iframe with a dark color-scheme, you would have to explicitly set the background to transparent, which is the opposite of how iframes normally work.

My take is that we should resolve this issue with no change.

@chrishtr
Copy link
Contributor

I think it would be web-compatible to do it for dark mode only, however. This is indeed a slight inconsistency between light and dark modes.

One other half-solution to the problem of overriding a UA-supplied canvas color in presence of dark mode: the developer can put an alternate opaque color on the HTML element, which will then completely obscure any black. This, however, does not work if the developer wishes to have any transparency on the iframe.

@AmeliaBR
Copy link
Contributor

One way of looking at the problem is that it's about a mis-match between the color-scheme of the parent frame and the iframe: the iframe says it supports a dark background, but the parent page is giving it a light one at the same time as the browser is switching all the other iframe styles over to dark mode.

I see two solutions:

  • When there is a mismatch in color scheme between the parent document and the iframe document, the browser should draw an opaque iframe canvas (in the correct background color for the iframe's root color scheme). The canvas remains transparent if the iframe element's color scheme is the same as the root element for its source document.

  • Ignore a supports-color-scheme: dark meta setting for the root of the iframe embedded content unless the parent document (or the iframe element in particular) is also in a dark color scheme.

    That doesn't address the reverse issue (the parent document is in dark mode but the embedded iframe doesn't support a dark mode), but hopefully the parent document's authors are more likely to test this situation (and add their own opaque background to the iframe), when they define the dark mode.

@chrishtr
Copy link
Contributor

chrishtr commented Feb 20, 2020

@AmeliaBR I like your first suggestion a lot - it provides a logical color backplate when embedding into a setting that is likely to have an incompatible color scheme. It should also be web-compatible, even for light iframes within a dark-mode parent.

@tomayac
Copy link
Contributor Author

tomayac commented Feb 20, 2020

@AmeliaBR I like your first suggestion a lot

+1, as a developer, this meets at least my expectations… :-)

@emilio
Copy link
Collaborator

emilio commented Feb 20, 2020

Doesn't that provide information from the parent document that the child document probably shouldn't have access to? Specially if the iframe is cross-origin.

@AmeliaBR
Copy link
Contributor

Doesn't that provide information from the parent document that the child document probably shouldn't have access to?

That's a good argument against my second proposal (change whether color-scheme has an effect or not, and therefore how the system colors evaluate in the embedded document).

But I don't think it would be a problem for the first proposal (draw an opaque canvas behind the iframe's root background when there's a mismatch), since I don't think there's any way for the document to read back the used canvas color.

@tabatkins
Copy link
Member

Right, the underlying canvas of a document isn't accessible to the page, so it should be undetectable when it happens.

@lilles
Copy link
Member

lilles commented Feb 20, 2020

Agree that solution 1 sounds good. Since color-scheme is specified per element, are we considering the used color-scheme of the parent document's root element, or the used color-scheme of the iframe element in the parent document?

@chrishtr
Copy link
Contributor

I think it makes sense to use the used color-scheme of the iframe element in the parent document, since that element may have an override relative to its document and corresponding
different colors that may not suffice as a good enough backplate for the iframe content.

@chrishtr
Copy link
Contributor

Agenda+ to achieve resolution on Amelia's first proposal: cause the canvas backdrop of an iframe to be drawn black or white if the color-scheme of the <iframe> element in the parent document differs from that of the root element of the iframe.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed `color-scheme` should affect embedded iframes, and agreed to the following:

  • RESOLVED: If the color scheme of an iframe differs from embedding document iframe gets an opaque canvas bg appropriate to its color scheme
The full IRC log of that discussion <dael> Topic: `color-scheme` should affect embedded iframes
<dael> github: https://github.com//issues/4772
<astearns> ack chris
<dael> Rossen_: This was added by Chrome folks
<dael> chrishtr: Problem with dark backplate behind iframe is it's not dev controllable. Prop is there be a white or black backplate of an iframe if the owner lemenet has a different color-scheme
<dael> chrishtr: A frame with an iframe have both dark you get that. One like and one dark backplate you get this.
<dael> chrishtr: backplate is the canvas behind the root element
<fremy> +1 to chrishtr's proposal
<dbaron> Is this specifically black/white background, or is it dark/light background? (i.e., are we requiring exactly black/white?)
<dbaron> (seems like it should match what's required for the root document)
<dael> jensimmons: Document canvas. We have legacy issue that iframes don't have document canvas but we also have expectation that if child document says it supports darkmode it assumes pat of that package is borwser painting dark canvas. One doc embadded in the other and one does darkmode switch things can get unreadbale. Proposal is iframe canavs is by default transparent unless mismatch between embedding element and root element. With mismatch you draw opaque canvas on
<dael> emilio: With used color scheme of iframe?
<dael> jensimmons: Yes. canavs system color of root element of iframe
<dael> emilio: Makes sense
<dbaron> s/jensimmons/AmeliaBR/
<dbaron> s/jensimmons/AmeliaBR/
<dael> AmeliaBR: Might not always be great for svg. Might need an issue that this may only apply to iframes or something. Not sure which is worse, color mismatch or chance at a transparent bakground. Specifically for webpage and iframe this should handle most cases. Open issue on svg
<dael> Rossen_: Detectable from within frame?
<dael> AmeliaBR: SHouldnt be. No way within doc to tell what the canvas color is b/c it's before root background so not accessible to cssom
<dael> emilio: Work for cross origin iframes?
<dael> Rossen_: That's why I asked. If there's additional information provided through mech to cross origin that's not today
<dael> AmeliaBR: Shouldn't be a way from embedded to tell if opaque drawn or not. Might be a user tricking way for paent doc to figure out if content is transparent based on if user can read content. I don't think there's a direct dom way outer document could tell
<dael> TabAtkins: Other than tricking user the information isn't exposed to embedding or embedder
<dael> emilio: Timing attacks from masking iframes and I'm assuming drawing opaque background is cheaper you could get creative
<dael> bkardell_: Is'tn that potential risk anyway?
<astearns> s/bkardell_ /chrishtr/
<dael> emilio: Would allow you to detect if there's a difference assuming you can detect painting of background
<dael> AmeliaBR: Maybe add a warning to avoid the timing attacks
<dino> s/the timing attacks/the timing attacks by taking care when optimising rendering into opaque iframes/
<dael> Rossen_: Besides the note sounds like consensus around how it should work. Any additional comments or objects to making the canvas of embedded documents match canvas of embedding document by either matching internal color scheme or applying opque cnavas in a case of mismatch
<dino> s/Is'tn/Isn't/
<dael> emilio: Assuming designing a doc designed to be embeddable can you design to match? I guess not and this does not slve. Mostly curious
<dael> AmeliaBR: That was my other proposal. The support color scheme option on child doc interp based on parent and that was poss cors issue b/c then child doc would be able to tell
<dael> emilio: Yeah
<dael> emilio: Okay. No concern.
<dael> Rossen_: I didn't hear objections
<dino> q+
<dael> TabAtkins: If the color scheme of an iframe differs from embedding document iframe gets an opaque canvas bg appropriate to its color scheme
<dael> ??: If owning doesn't provide color?
<dael> AmeliaBR: Legacy color scheme is still considered
<dael> RESOLVED: If the color scheme of an iframe differs from embedding document iframe gets an opaque canvas bg appropriate to its color scheme
<dino> s/??/dino/
<emilio> s/??/dino (I think?)
<emilio> heh :)

@fantasai
Copy link
Collaborator

fantasai commented Mar 6, 2020

Edited in. @AmeliaBR would you mind reviewing? :)

@AmeliaBR
Copy link
Contributor

AmeliaBR commented Mar 6, 2020

The text looks good, @fantasai, except that Bikeshed is linking the “canvas” keyword to an SVG definition about coordinate systems.

The most useful link would probably be the "Backgrounds of Special Elements" section of CSS Backgrounds, although it in turn links back to CSS 2 for the theoretical definition of a canvas.

@fantasai
Copy link
Collaborator

Thanks, @AmeliaBR ! Fixed!

@lilles
Copy link
Member

lilles commented Mar 12, 2020

moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Mar 15, 2020
… a=testonly

Automatic update from web-platform-tests
Add tests for color-scheme and iframes.

Iframes where the color-scheme of the iframe element and the iframe
document's root does not match, will get a backdrop matching the color-
scheme of the iframe's root element.

Also adjust existing test according to spec change. See:
w3c/csswg-drafts#4772

Bug: 1058822
Change-Id: I82fd3cc3c2bbf5b4835b157a7522cb22c459ff20
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2095112
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#750186}

--

wpt-commits: 348adc5c7b2e3abb76763af063fbd921afb99ac5
wpt-pr: 22213
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this issue Mar 16, 2020
… a=testonly

Automatic update from web-platform-tests
Add tests for color-scheme and iframes.

Iframes where the color-scheme of the iframe element and the iframe
document's root does not match, will get a backdrop matching the color-
scheme of the iframe's root element.

Also adjust existing test according to spec change. See:
w3c/csswg-drafts#4772

Bug: 1058822
Change-Id: I82fd3cc3c2bbf5b4835b157a7522cb22c459ff20
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2095112
Reviewed-by: Anders Hartvoll Ruud <andruudchromium.org>
Commit-Queue: Rune Lillesveen <futharkchromium.org>
Cr-Commit-Position: refs/heads/master{#750186}

--

wpt-commits: 348adc5c7b2e3abb76763af063fbd921afb99ac5
wpt-pr: 22213

UltraBlame original commit: e0db51ee811dc6abb6d0897bbbf56a8ed8fdb1f0
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this issue Mar 16, 2020
… a=testonly

Automatic update from web-platform-tests
Add tests for color-scheme and iframes.

Iframes where the color-scheme of the iframe element and the iframe
document's root does not match, will get a backdrop matching the color-
scheme of the iframe's root element.

Also adjust existing test according to spec change. See:
w3c/csswg-drafts#4772

Bug: 1058822
Change-Id: I82fd3cc3c2bbf5b4835b157a7522cb22c459ff20
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2095112
Reviewed-by: Anders Hartvoll Ruud <andruudchromium.org>
Commit-Queue: Rune Lillesveen <futharkchromium.org>
Cr-Commit-Position: refs/heads/master{#750186}

--

wpt-commits: 348adc5c7b2e3abb76763af063fbd921afb99ac5
wpt-pr: 22213

UltraBlame original commit: e0db51ee811dc6abb6d0897bbbf56a8ed8fdb1f0
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this issue Mar 16, 2020
… a=testonly

Automatic update from web-platform-tests
Add tests for color-scheme and iframes.

Iframes where the color-scheme of the iframe element and the iframe
document's root does not match, will get a backdrop matching the color-
scheme of the iframe's root element.

Also adjust existing test according to spec change. See:
w3c/csswg-drafts#4772

Bug: 1058822
Change-Id: I82fd3cc3c2bbf5b4835b157a7522cb22c459ff20
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2095112
Reviewed-by: Anders Hartvoll Ruud <andruudchromium.org>
Commit-Queue: Rune Lillesveen <futharkchromium.org>
Cr-Commit-Position: refs/heads/master{#750186}

--

wpt-commits: 348adc5c7b2e3abb76763af063fbd921afb99ac5
wpt-pr: 22213

UltraBlame original commit: e0db51ee811dc6abb6d0897bbbf56a8ed8fdb1f0
JTensai pushed a commit to JTensai/csswg-drafts that referenced this issue May 13, 2020
@emilio
Copy link
Collaborator

emilio commented Oct 28, 2021

@lilles hmm, so Blink ended up implementing this even for cross-origin iframes? That seems not-amazing... Can that be observed by the page in any way? It seems the kind of thing that has been time-able in the past...

moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Nov 20, 2021
… r=dholbert

There's two kinds of test failures remaining:

 * Failures related to how system colors inherit, which is something
   that no engine is shipping and I'm not convince it's a good thing:
   w3c/csswg-drafts#6773

 * Failures related to <iframes> observing color-scheme of ancestors
   (which Chrome does implement but Safari doesn't):
   w3c/csswg-drafts#4772
   https://bugzilla.mozilla.org/show_bug.cgi?id=1738380
   I'm unconvinced that should work across cross-origin iframes though
   (see the question at the end of that issue), and it seems delaying
   shipping it blocked on figuring that out while other engines ship
   diverging behaviors is probably not worth it.

Given privileged code is already using this and we know of no other
blockers, I think it's fine to let it ride the trains.

Differential Revision: https://phabricator.services.mozilla.com/D131635
jamienicol pushed a commit to jamienicol/gecko that referenced this issue Nov 22, 2021
… r=dholbert

There's two kinds of test failures remaining:

 * Failures related to how system colors inherit, which is something
   that no engine is shipping and I'm not convince it's a good thing:
   w3c/csswg-drafts#6773

 * Failures related to <iframes> observing color-scheme of ancestors
   (which Chrome does implement but Safari doesn't):
   w3c/csswg-drafts#4772
   https://bugzilla.mozilla.org/show_bug.cgi?id=1738380
   I'm unconvinced that should work across cross-origin iframes though
   (see the question at the end of that issue), and it seems delaying
   shipping it blocked on figuring that out while other engines ship
   diverging behaviors is probably not worth it.

Given privileged code is already using this and we know of no other
blockers, I think it's fine to let it ride the trains.

Differential Revision: https://phabricator.services.mozilla.com/D131635
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue May 21, 2022
…lor schemes. r=jwatt

In the future we might want to (also?) propagate the
prefers-color-scheme on the iframe like we do for the content/chrome
boundary / top browsing contexts, see:

 * w3c/csswg-drafts#4772
 * w3c/csswg-drafts#7213

Differential Revision: https://phabricator.services.mozilla.com/D146162
emilio added a commit to emilio/uBlock that referenced this issue May 25, 2022
This fixes the element picker on dark color-scheme websites on
Firefox Nightly and Chrome Canary at least, see:

  * https://bugzilla.mozilla.org/show_bug.cgi?id=1771047
  * w3c/csswg-drafts#4772

This also removes the existing (not quite correct, was relying on a
Chromium bug) fix for Chromium browsers.

The dom inspector scriptlet had the same issue (so I fixed it as well).
jamienicol pushed a commit to jamienicol/gecko that referenced this issue May 25, 2022
…lor schemes. r=jwatt

In the future we might want to (also?) propagate the
prefers-color-scheme on the iframe like we do for the content/chrome
boundary / top browsing contexts, see:

 * w3c/csswg-drafts#4772
 * w3c/csswg-drafts#7213

Differential Revision: https://phabricator.services.mozilla.com/D146162
emilio added a commit to emilio/uBlock that referenced this issue Jun 1, 2022
This fixes the element picker on dark color-scheme websites on
Firefox Nightly and Chrome Canary at least, see:

  * https://bugzilla.mozilla.org/show_bug.cgi?id=1771047
  * w3c/csswg-drafts#4772

This improves on the existing (not quite correct, was relying on a
Chromium bug) fix for Chromium browsers.
luizdepra pushed a commit to luizdepra/hugo-coder that referenced this issue Nov 28, 2022
### Prerequisites

- [x] This pull request fixes a bug.
- [x] This pull request adds a feature.
- [ ] This pull request introduces breaking change.

### Description

This PR fixes the bug about disqus iframe background in dark mode, it
also fix another bug when switching color mode.

Before:
<img width="881" alt="opaque background in dark mode"
src="https://user-images.githubusercontent.com/17041194/202862887-720dbb82-f0c8-4a24-97fd-78baef2a7cb4.png">

After:
<img width="883" alt="CleanShot 2022-11-20 at 01 12 52@2x"
src="https://user-images.githubusercontent.com/17041194/202863146-d5a246a7-bbe5-4bef-9687-883ce33f5b1a.png">

#### Why this happens

The problem is widely discussed
[here](w3c/csswg-drafts#4772).

>If the color scheme of an iframe differs from embedding document,
iframe gets an opaque canvas bg appropriate to its color scheme.

So I made two fixes:

1. Add `color-scheme: light` CSS property for disqus `iframe`, this
creates a transparent background and fixes the opaque issue.
2. Add `themeChanged` event to notice disqus comments board refresh when
the theme change, this fixes the opaque problem when you switch the
mode.

#### Reference

I've been working on this issue for a whole night and the fixing idea
was strongly inspired by [Sergeyski's
Blog](https://sergeyski.com/css-color-scheme-and-iframes-lessons-learned-from-disqus-background-bug/).

### Issues Resolved

Fixes #722.
eshack94 pushed a commit to eshack94/hugo-coder that referenced this issue Dec 21, 2022
### Prerequisites

- [x] This pull request fixes a bug.
- [x] This pull request adds a feature.
- [ ] This pull request introduces breaking change.

### Description

This PR fixes the bug about disqus iframe background in dark mode, it
also fix another bug when switching color mode.

Before:
<img width="881" alt="opaque background in dark mode"
src="https://user-images.githubusercontent.com/17041194/202862887-720dbb82-f0c8-4a24-97fd-78baef2a7cb4.png">

After:
<img width="883" alt="CleanShot 2022-11-20 at 01 12 52@2x"
src="https://user-images.githubusercontent.com/17041194/202863146-d5a246a7-bbe5-4bef-9687-883ce33f5b1a.png">

#### Why this happens

The problem is widely discussed
[here](w3c/csswg-drafts#4772).

>If the color scheme of an iframe differs from embedding document,
iframe gets an opaque canvas bg appropriate to its color scheme.

So I made two fixes:

1. Add `color-scheme: light` CSS property for disqus `iframe`, this
creates a transparent background and fixes the opaque issue.
2. Add `themeChanged` event to notice disqus comments board refresh when
the theme change, this fixes the opaque problem when you switch the
mode.

#### Reference

I've been working on this issue for a whole night and the fixing idea
was strongly inspired by [Sergeyski's
Blog](https://sergeyski.com/css-color-scheme-and-iframes-lessons-learned-from-disqus-background-bug/).

### Issues Resolved

Fixes luizdepra#722.
danielwiehl added a commit to SchweizerischeBundesbahnen/scion-microfrontend-platform that referenced this issue Oct 26, 2023
An iframe is transparent only if the embedded content has the same color scheme as the embedding document.

An empty router-outlet loads the 'about:blank' page. This page has the user's preferred OS color scheme, which may be different from the application's color scheme, making the iframe opaque. Therefore, we hide the iframe to make the router-outlet transparent again.

More information about iframe transparency:
- w3c/csswg-drafts#4772 (comment)
- https://fvsch.com/transparent-iframes
Marcarrian pushed a commit to SchweizerischeBundesbahnen/scion-microfrontend-platform that referenced this issue Oct 26, 2023
An iframe is transparent only if the embedded content has the same color scheme as the embedding document.

An empty router-outlet loads the 'about:blank' page. This page has the user's preferred OS color scheme, which may be different from the application's color scheme, making the iframe opaque. Therefore, we hide the iframe to make the router-outlet transparent again.

More information about iframe transparency:
- w3c/csswg-drafts#4772 (comment)
- https://fvsch.com/transparent-iframes
@AmeliaBR
Copy link
Contributor

AmeliaBR commented Apr 1, 2024

Since someone just asked me about this issue:

We still do not have cross-browser compat on the matter of opaque iframe backgrounds when there is a color-scheme mismatch. See wpt.fyi summary.

Are there additional spec issues still being debated, or should there be some pressure on the browser teams to get this done?

@tabatkins
Copy link
Member

Nope, spec is fine, it's still just a browser bug. One of our engineers recently ran into it again when designing a personal site, and filed another bug for it. ^_^

@chrishtr
Copy link
Contributor

chrishtr commented Apr 18, 2024

Note: the only bug I could find for Chromium was this one (which was fixed this week by @lilles, thanks!)

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

9 participants