Closed Bug 50623 Opened 21 years ago Closed 20 years ago

Background transparency isn't honored inside OBJECT's and IFRAME's


(Core :: Web Painting, defect)

Not set





(Reporter: bugmail, Assigned: roc)




(Keywords: css1, testcase)


(3 files, 2 obsolete files)

An IFRAME that specifies no background style, embedded in a document with a
specified background style, is rendered with the background of the default
viewport or canvas, when it should probably display with no background, or a
theoretical "transparent" background.

Reproducibility: every time.

Steps to reproduce: Load the specified example case URL

Actual results: Observe that the page renders with an overall blue background,
but the IFRAME displays with whatever color is specified as the default
background color in the browser preferences.

Expected results: The IFRAME should display with no background; that is, a
theoretically "transparent" background, resulting in the text "This is bar."
being rendered on a blue background.

Additional information: I verified the behavior with the 8/28 M18 daily build as

This "bug" may simply be a misinterpretation of the intended background of an
IFRAME element or how background colors and images are inherited from the
embedding document and the viewport or canvas.

It's important to consider what would happen if instead of a solid blue
background, a more complex image were used as a background instead. In such a
case, the background image shouldn't be retiled again at the top-left corner of
the IFRAME; the IFRAME should, I believe simply be "transparent", as specified

This also conjurs up notions of fully "transparent" (or, god forbid,
translucent) pages, but I don't believe that issue needs to be addressed to fix
this bug, which is only intended to address the backgrounds of IFRAMEs embedded
in HTML or XML documents. (Note also that OBJECT functionality is tested in the
example, but as text/html OBJECT embedding is presently nonfunctional it cannot
be tested.)
It would be nice, but it is not critical, so we'll get to it during a future
feature train (we are currently concentrating on stability fixes).

Moving to Views, which I believe is the right component...
Assignee: pierre → kmcclusk
Component: Style System → Views
Ever confirmed: true
Keywords: css1
OS: Mac System 9.0 → All
Hardware: Macintosh → All
Target Milestone: --- → Future
This can and should be fixed, but after NS6 ships, and probably even post 
Mozilla 1.0.

I think the best way is to just have just one nsViewManager for an entire 
document and all its subdocuments. In other words, the root view of an IFRAME 
document is not the root of the view tree. Such a view would have to be 
specially marked as a document root view to make fixed-position elements attach 
to the right parent, but there's nothing on the view manager side to make any of 
this difficult. The difficulties are probably in places like the docshell where 
it assumes it controls its own view manager.

Once there's just one view manager for the entire document set, transparency, 
translucency and other tricks are easily taken care of.
Summary: IFRAME element that specifies no background itself doesn't interact properly with background of embedding document → IFRAME element that specifies no background itself doesn't interact properly with background of embedding document [BG]
QA Contact: chrisd → petersen
*** Bug 75718 has been marked as a duplicate of this bug. ***
Keywords: testcase
Since bug 678 has been fixed, this now applies to OBJECT elements as well as
IFRAME elements.
is this a helpwanted bug?
Summary: IFRAME element that specifies no background itself doesn't interact properly with background of embedding document [BG] → Transparent documents in OBJECT's and IFRAME's aren't displayed transparently.

Ive filed a request for a possible work around (for background color) if the 
iframe transparency fix is post 1.0 (see 105821) ....

.... but I too would love to see iframe transparency fixed for 1.0 to eliminate 
the default white background 
Summary: Transparent documents in OBJECT's and IFRAME's aren't displayed transparently. → Background transparency isn't honored inside OBJECT's and IFRAME's
I am planning to (very soon) add support in the view system for transparent IFRAMEs.

However, with our current style rules an IFRAME will not be transparent by
default. We treat it just like a top-level document; it has a canvas whose
background is always set according to user prefs or system colours, if not by
the document itself. However, you will probably be able to force it to be
transparent by putting this rule in a style sheet:
:canvas { background: transparent; }

Giving IFRAMEs a transparent background by default would require a little more
work and be a significant policy decision, so ccing W3C standards gurus.
OK, I now have support for this in my tree. However, you won't be getting
transparent backgrounds by default. You'll have to use funky style rules to set
Assignee: kmcclusk → roc+moz
To get this to work I added the following to my userContent.css:

html, body, *|*:viewport, *|*:viewport-scroll, *|*:canvas, *|*:root {
background: transparent; }
The mechanism for this landed a while ago. If you add those horrible styles to
your IFRAME document it should be transparent. Now we're just waiting for the
W3C gurus to tell us when exactly an IFRAME should be transparent.
Severity: normal → minor
Priority: P3 → --
Target Milestone: Future → mozilla1.1
Robert, does this work for both IFRAME and OBJECT?
Incorporating Robert's userContent.css settings, the testcase URL does now
appear to work as expected using Mac/2002022108.
I guess looks like safe to enable this when pages are specifying
background-color transparent for the body element. Example

<body style="background-color:transparent">. This will really enable a new world
of possibilities. I am thinking.. can I plugin canvas have transparent
background? will flash transparent work? 
Adding few DHTML gurus. 
Plugins won't generally work with transparency. They will appear completely
opaque. (There is some support for transparent plugins but I don't think the
plugin vendors use it.)
About the plugins, bug 99974 is about transparency in Flash movies.
I believe that IFRAMEs and so forth should not be transparent by default, but
should act as transparent if their background is set to 'transparent'.
I presume you mean that they should be transparent if the background on the BODY
and HTML elements of the contained document is set to "transparent". Right?
That would work. Note that if the frame is empty it should still be white --
that should not be a problem because about:blank is an HTML document with a BODY
element which should be getting its background from html.css.

Except I don't think we do it that way at the moment -- aren't all body elements
transparent by default?
Why should an iframe that is empty be white instead of transparent?
why do we even have the 

*|*:viewport, *|*:viewport-scroll, *|*:canvas

rules (*|*:root seemsto be gone)? Shouldn't they simply be killed? Is there a
bug tracking that? (or is that bug this bug :) )
I tested this with Ian's background tests, some general surfing, and some
complex IFRAME tests I made up. It has the effect of making IFRAMEs transparent
by default because their documents don't have any background set (of course, if
an IFRAME specifies a background on its HTML or BODY element, it is honoured).
I recommend that this be checked in.
Ian should review this patch.

Note that it makes about:blank frames (and any document without background
explicitly set) transparent. Our mechanism for setting prefererred/system
background colors only applies to the root document (and it still works, I
checked). If we want to apply that mechanism to subdocuments (and I don't
actually see why we should) then file another bug about that but still check in
this patch.
Attached patch Better patch (obsolete) — Splinter Review
This patch includes the previous patch and adds a fix that makes "background"
styles work on frames. This is very useful now that the document contained in a
frame can be transparent; the background of the frame element in the enclosing
document will be visible.

The background style fix undoes a hack that I did in patch 49779. Since that
bug we've added the new CanPaintBackground method which is a cleaner way to
handle frames that don't paint backgrounds.
Attachment #85000 - Attachment is obsolete: true
I don't understand really the patch itself. Let me see if I can understand what
it does, though.

First, what are the defaults. An unspecified background color for the root
element of a document results in a computed background of 'transparent'? Does
the ::canvas then have a default background that matches the user's colours?
Do <frame>s default (due to CSS initial values) to a 'transparent' background?

If so, would the following describe the effect of the patch?:

   Document   |   <frame>    |  Subdocument  |   Result
  Background  |  Background  |  Background   |   
 unspecified  | unspecified  | unspecified   | Document shines through to be
              |              |               | the subdocument's background, so
              |              |               | typically the user's preferred
              |              |               | colours are used.
              |              |               |
 red          | green        | transparent   | Subdocument background is green.
              |              |               |
 red          | maroon       | green         | Subdocument background is green.
              |              |               |
 green        | rgba(1,1,1,1)| rgba(2,2,2,2) | rgba(2,2,2,2) composited on top
              |              |               | of rgb(1,1,1,1) composited on top
              |              |               | of green.
              |              |               |
> An unspecified background color for the root
> element of a document results in a computed background of 'transparent'?


> Does the ::canvas then have a default background that matches the user's
> colours?

The CSS background for all ::canvases is transparent, but dbaron's painting code
ensures that when we paint the background for the ::canvas of a document at the
root of a document tree, we use the user's colours.

> Do <frame>s default (due to CSS initial values) to a 'transparent'
> background?


> If so, would the following describe the effect of the patch?

Cool. Technically at least, that sounds good to me.

We may need to make <iframe>s have non-transparent backgrounds in quirks mode,
though, if there are sites that are affected by this in odd ways.
So, does this need the "review" keyword now?
There's just one thing I'm a little worried about. I don't know why frames
aren't transparent today! The initial value for "background-color" is
"transparent" in CSS2, and that's what we seem to implement. "-moz-viewport",
"-moz-viewport-scroll" and "-moz-canvas" should all be inheriting that, so the
guts of this patch (removing the "inherit", giving them the initial value of
"transparent") should have no effect! Yet it does. I've stared at the code but I
can't figure out how -moz-viewport is inheriting anything other than
"transparent". Maybe dbaron can help me out...
The nsStyleBackground constructor for the root style context (taking an
nsIPresContext) initializes background differently.  Also see
Comment on attachment 85004 [details] [diff] [review]
Better patch

Attachment #85004 - Flags: superreview+
dbaron, you're talking about
right? That seems to make the root style context transparent. Maybe the
BG_IS_TRANSPARENT flag is somehow being ignored so the prescontext colour is
used, but I don't see how.

I know about FindBackground but that doesn't affect the styles inherited into
the viewport.
Oh, you're right about the nsStyleBackground constructor.  How about the code in
nsCSSRendering::PaintBackground (not FindBackground)?
Heh. Are we still trying to work out how the canvas background ends up being
painted? IIRC Pierre couldn't work that out either, about 2 years ago...
PaintBackground ignores a transparent canvas and paints it with the default
colour BUT ONLY for root documents, not (since my changes in the 0.9.9
timeframe) for framed documents. So that doesn't explain why the current code
paints the canvases of framed documents.

Anyway (unless I'm on crack) the current code behaves differently with when I
change ":-moz-viewport { background-color: inherit; }" to ":-moz-viewport {
background-color: transparent; }", which makes no sense since it should be
inheriting transparent and so no difference should be visible outside the style

OK, so no-one knows what's going on. I'll try some more invasive analysis.
HA. So I just uncovered a subtle but potentially serious style system bug.

nsRuleNode.cpp has lots of constructs like this:
> bg->mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT;
> bg->mBackgroundFlags |= (parentBG->mBackgroundFlags &

Looks fine, doesn't it? But think about the case when bg == parentBG. This
happens whenever parentContext is null but it can happen for various settings of
ruleDetail. The only reason we don't get burned much is because the default
style context doesn't have many flags set so not much gets accidentally dropped.
Attached patch The REAL fixSplinter Review
Here's the real fix: stop the style system from forgetting about transparency
when bg == parentBG. Also fixes <frame>/<iframe> frames to draw backgrounds, as
noted above.
Attachment #85004 - Attachment is obsolete: true
Comment on attachment 85585 [details] [diff] [review]
The REAL fix

r=dbaron, except:

Why doesn't the FRAME/IFRAME paint its background when it has a nontransparent
one?  (In other words, why do you need to add the |CanPaintBackground|
override?)  It looks like you're changing it so that's not necessary.

Also, the comment in the nsRuleNode.cpp change should either say "save
parentFlags" or "save parent flags" rather than "save parentFlag".
Attachment #85585 - Flags: review+
> Why doesn't the FRAME/IFRAME paint its background when it has a
> nontransparent one?  (In other words, why do you need to add the
> |CanPaintBackground| override?)  It looks like you're changing it so that's
> not necessary.

FRAME/IFRAME elements generate two frames. nsFrameOuterFrame paints the
background, but nsFrameInnerFrame does not (and that's where the
CanPaintBackground() -> PR_FALSE is).

> Also, the comment in the nsRuleNode.cpp change should either say "save
> parentFlags" or "save parent flags" rather than "save parentFlag".

I'll fix that.
OK, makes sense to me.
I just want to clarify something for posterity:

As it stands this patch is just bugfix and cleanup. It turns out our policy as
expressed in CSS rules was already to make FRAME/IFRAME transparent by default,
it just wasn't implemented correctly :-). If we get feedback that FRAME/IFRAME
should not be transparent by default then the solution is NOT to rollback this
patch, but to modify the style system so that every ::viewport has its
background colour set in CSS to the user's preferred colour.
Keywords: review
Comment on attachment 85585 [details] [diff] [review]
The REAL fix

Attachment #85585 - Flags: superreview+
Checked into trunk.
Closed: 20 years ago
Resolution: --- → FIXED
This broke Tinderbox.

Specifically, it made the <iframe>s that appear when you click someone's name
appear transparent, which looks really ugly. This is what I thought might happen
(see comment 28). What do we want to do about this? I think per the spec, we are
justified in our behaviour (the <iframe>'s infinite canvas is merely
transparent) but do we really want to evangelise any sites that this breaks? Is
this a quirks/standards thing?

It's not THAT bad, I wouldn't say it "broke" Tinderbox. Actually it shows how
useful transparent IFRAMEs will be: the Tinderbox people should set the popup
IFRAMEs to have no border, then you get the effect of IFRAMEed content that
sizes to fit the contents, which you can't get otherwise.

I'll try to prepare a patch that restores the old behavior by setting the
initial background for the viewport. Once we collect more feedback we can decide
whether or not to apply the patch.
If we did that, what would be the standards-compliant CSS that would make the
iframe transparent again?
I guess we should set the initial background for the root element, so that <html
style="background: transparent"> would suffice.
Setting the <html> background doesn't work because that screws up the
body->canvas inheritance path. I guess this can't be done with style rules. I'll
hack FindBackground/PaintBackground instead.
OK, I'm stumped.

If we use CSS rules to set the style on <HTML> to anything non-transparent, then
we break the propagation of non-transparent <BODY> to the canvas. But if we
don't use CSS rules to set the style on <HTML>, then how can authors get a
transparent background in a standards-compliant way?
How about putting the background on the <iframe> itself, so that authors wanting
transparent iframes just have to say:

   iframe { background: transparent; }

...? Would that work?
Yes! That's a brilliant idea and it does work. Patch coming up.
Comment on attachment 85926 [details] [diff] [review]
Give IFRAMEs the user's preferred background

You're going to want to put those selectors in the HTML namespace somehow. 
(This stylesheet should probably be rewritten as a separate C++ implementation
of nsIStyleSheet at some point.  Perhaps this is the time.)
nsPresShell sets XHTML as the default namespace for the style sheet:
>        mPrefStyleSheet->SetDefaultNameSpaceID(kNameSpaceID_XHTML);
Isn't that good enough?
OK.  Never mind...
Well, do mind. The ":root" and "*" selectors should be in all namespaces,
otherwise this will only work for (X)HTML documents. Also, we should add
pseudo-elements, otherwise authors can override this.

So the rules in the second part should be:

   *|*:root {
     color: bla ! important; background: bla ! important;
   *|*, *|*:before, *|*:after, *|*:first-line, *|*:first-letter {
     color: inherit ! important; background: transparent ! important;

And of course that's ignoring the mirad :-moz-* pseudo-elements that we're
leaving open to abuse...
That will cause the creation of lots of pseudo-element frames that we don't need
in the case where the override pref is checked.

We really need to redo the way these prefs work (the override ones should be
handled in nsRuleNode.cpp).
In nsRuleNode.cpp can we determine whether the styled element(s) belong to
content to which prefs should be applied?

If we had some internal rule selector that applied to absolutely everything, we
could use that.

It really shouldn't create new pseudo-element nodes unless our code is on crack,
since those rules specifically put those pseudo-elements back to their initial
values, in the case of :first-line and :first-letter, and don't affect the
'content' property, in the case of :before and :after.

A magic pseudo-element that applies to all elements, real and fake, might be
best though, I guess. Hey, you guys are the experts. :-)
I'm curious --- why doesn't * apply to pseudoelements? It seems a bit strange to
have a selector that selects everything except pseudoelements.
It's a theoretical thing. It basically doesn't fit into the CSS conceptual model.
The * is the type selector which is implied in ".class". Having that also mean
".class::before" would be bad. And so on.
Adding mkaply

Tis is the bug that caused iframes to have transparent backgrounds; there's a
patch here that changes that.
Component: Layout: View Rendering → Layout: Web Painting
You need to log in before you can comment on or make changes to this bug.