Closed Bug 697946 Opened 8 years ago Closed 8 years ago

negative z-index block element that is child of body is visible but not clickable when body is not a stacking context

Categories

(Core :: Web Painting, defect)

defect
Not set

Tracking

()

RESOLVED INVALID

People

(Reporter: bradley.schaefer, Unassigned)

References

(Blocks 1 open bug)

Details

(Keywords: testcase)

Attachments

(5 files)

Attached file link is unclickable
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.106 Safari/535.2

Steps to reproduce:

Created a positioned block element with a negative z-index 


Actual results:

The block element is visible, and the text of a link is selectable, however the link itself is not actually clickable.

I did find a workaround: the link becomes clickable if you set the z-index on body to be less than the block element and give it a position: relative


Expected results:

The link should be clickable.

This may be a duplicate of a couple 'fixed' bugs that I dug up (they don't seem fixed to me):

https://bugzilla.mozilla.org/show_bug.cgi?id=96832
https://bugzilla.mozilla.org/show_bug.cgi?id=559499
Attachment #570201 - Attachment mime type: text/plain → text/html
Well, the testcase in bug 559499 certainly works....
So as expected, the event display list for a click on that link is:

Background 0x66af120(HTMLScroll(html)(-1)) (0,0,77760,52800)(0,0,0,0) uniform
Clip 0x0() (0,0,77760,52800)(0,0,0,0)
    CanvasBackground 0x66aef48(Canvas(html)(-1)) (0,0,77760,52800)(0,0,0,0) uniform
    Background 0x7e878f8(Block(html)(-1)) (0,0,77760,2112)(0,0,0,0) uniform
Clip 0x7e880e8(Block(div)(1)) (0,0,77760,52800)(0,0,0,0)
    WrapList 0x7e880e8(Block(div)(1)) (420,480,76860,1152)(0,0,0,0)
        Background 0x7e880e8(Block(div)(1)) (480,480,76800,1152)(0,0,0,0) uniform
        Background 0x665c888(Inline(a)(1)) (480,576,1972,960)(0,0,0,0) uniform
        Text 0x665c8d0(Text(0)) (420,576,2092,960)(0,0,0,0)
Clip 0x0() (0,0,77760,52800)(0,0,0,0)
    Background 0x7e87e80(Block(body)(2)) (480,480,76800,1152)(0,0,0,0) uniform

roc, I thought the spec changed to put backgrounds under negative-z-index stuff....
And for a non-body parent, that is exactly what happens.  So where is that Background display item for the body coming from?
Ah, I see.  So the issue is that the body is NOT a stacking context.  The background of a stacking context goes below the negative-z-index things, but the backgrounds of its not-stacking-context descendants go over them, per spec.  My non-body-parent example had that parent being a stacking context.

So the only real issue here is that we're creating the background item there even when the body background is propagated to the viewport.  For painting we then ignore it, but event delivery doesn't know to do that.  That seems wrong.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Summary: negative z-index block element is visible and selectable, but not clickable → negative z-index block element that is child of body is visible but not clickable when body is not a stacking context
Thanks for distilling the test case into a minimal example - the other bit I'd left in was a justification for doing this.

I agree with you that bug 559499 works/is fixed, sorry to imply it wasn't wasn't; they just seemed very similar.
Attached file root table
Is this link expected to work too?
Attached file display:inline
... and the display:inline case too?
Keywords: testcase
OS: Mac OS X → All
Hardware: x86 → All
> Is this link expected to work too?

Hard to say.  Probably yes.

> ... and the display:inline case too?

That style is ignored on the root; other than that I _think_ it should work, yes.
Attached patch wip1Splinter Review
Moving the background item after the lists have been built seems to work.
Would it be better do it directly when building the lists? in DisplayLine:
http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsBlockFrame.cpp#6127
I'm confused. The positioned element is under the body in z-order. Whether or not the body has a background (or where that background is propagated to) should not affect z-order and event propagation (since we don't make any attempt to make invisible elements automatically transparent to events). As far as I can tell, the entire container DIV *should* be unclickable. Am I missing something?
Hmm.  When you put it that way, I don't think you're missing anything, no....
As far as I can tell, our behavior follows the spec.
Status: NEW → RESOLVED
Closed: 8 years ago
Resolution: --- → INVALID
If the div should be unclickable, shouldn't it be invisible? If you give the body a background color and the container a background color, you can still see the container, so this isn't relating to the body being transparent.
In general, invisible stuff can be unclickable.  Try this:

  <div style="position: absolute; top:0 left:0; z-index: 1">
    <a href="http://example.com">Can you click me?</a>
  </div>
  <div style="position: absolute; top: 0; left: 0; width: 500px; height: 500px; z-index: 2">
  </div>
I agree with the behavior of your latest example - but this is not the behavior I'm describing. If you give your divs background-colors then the link is correctly hidden.

<div style="position: absolute; top:0 left:0; z-index: 1; background-color: yellow">
    <a href="http://example.com">Can you click me?</a>
  </div>
  <div style="position: absolute; top: 0; left: 0; width: 500px; height: 500px; z-index: 2; background-color: green">
</div>

If you give the body element a background you would think it would cover the link as well - but it does not.


<!DOCTYPE html>
<html>
  <head>
    <style type="text/css">
      body {
          background-color: green;
      }
      .container {
          position: relative;
          z-index: -20;
          background-color: yellow;
      }

    </style>
  </head>
  <body>
    <div class="container">
      <a href="#">linky</a>
    </div>
  </body>
</html>
> If you give the body element a background you would think it would cover the link as well

No, because the body's background is painted on the viewport if there is no background on the <html>.  But that doesn't change whether the <body> is above the <div> in your testcase or not; it just changes where the background is painted.  You can test this trivially by putting a background on the <html>; suddenly the green paints above the <div>... but the actual z-ordering of the two boxes hasn't changed, of course.  Just the painting of the background.

You can see this clearly if you change the styles from comment 16 as follows: put a 10px solid green borer on the body, remove the background from the body, and give the <div> "top: 10px".  The border paints over the div, because the entire <body> box is above the <div>.
Oh, wow, I did not realize that the body background was a special case like that. I appreciate your example(s) and explanation.

I will say that this behavior is a bit odd to me - I might think that setting a background on the body element (with no html background) would paint on the viewport AND on the element, rather than just the viewport. Maybe that would be outside of spec though
I tested other UAs with a (propagated) non-transparent background - it makes the link
unclickable in Chrome and Opera, but still clickable in IE9.  So it seems the only
reason the link is clickable in the former is that the background is transparent.

I think it's unfortunate that the painting order doesn't match the event hit test
z-order in the case of a propagated backgrounds, but given that we're compatible
with Chrome/Opera for non-transparent backgrounds it doesn't seem worth trying to
change the spec.

Perhaps we should just give in and fix bug 102695 ;-)
Blocks: 102695
> Maybe that would be outside of spec though

Yeah, it would.  The spec on body backgrounds is actually pretty clear as these things go...  http://www.w3.org/TR/CSS21/colors.html#background says:

  For documents whose root element is an HTML "HTML" element or an XHTML "html" element
  that has computed values of 'transparent' for 'background-color' and 'none' for
  'background-image', user agents must instead use the computed value of the background
  properties from that element's first HTML "BODY" element or XHTML "body" element child
  when painting backgrounds for the canvas, and must not paint a background for that
  child element.

> Perhaps we should just give in and fix bug 102695 ;-)

That would be why it's clickable in IE9, presumably.
Component: Layout: View Rendering → Layout: Web Painting
You need to log in before you can comment on or make changes to this bug.