Closed Bug 133165 Opened 22 years ago Closed 20 years ago

outline doesn't include larger descendants of inline elements

Categories

(Core :: CSS Parsing and Computation, defect, P4)

defect

Tracking

()

RESOLVED FIXED
Future

People

(Reporter: reidr, Assigned: roc)

References

()

Details

(Keywords: css-moz, css2, testcase, Whiteboard: [Hixie-P3])

Attachments

(4 files, 1 obsolete file)

Awhile ago, I found the following somewhere and added it to my userContent.css file:

a:link:hover {
  -moz-outline: 1px dotted blue;
}

It puts a dotted box around links the pointer is hovering over.  In some cases,
the box drawn around the links is the wrong size, though.  This can often happen
with a large image, for example, in which case the box might only draw from the
bottom to halfway up the image, cutting it in half.

I'll try to attach an image showing the problem.

Using nightly from 20020324.
The image shows a portion of my Yahoo home page.  The pointer was on the "My
Yahoo" link, so the box was drawn around the image, but it cuts the image in
half vertically.
->Style system
Assignee: asa → dbaron
Status: UNCONFIRMED → NEW
Component: Browser-General → Style System
Ever confirmed: true
Keywords: css-moz
QA Contact: doronr → ian
this is probably a dup, there are various outline bugs already
Believe it or not, I don't think we have another bug on this.  Technically the
current behavior is OK, but it's not preferable, and I know I've commented at
length somewhere about how we should be doing this.  I just can't find it.
Blocks: css2outline
Status: NEW → ASSIGNED
Priority: -- → P4
Summary: a:link:hover with -moz-outline draws incorrectly-sized box → -moz-outline draws incorrectly-sized box
Target Milestone: --- → Future
Summary: -moz-outline draws incorrectly-sized box → -moz-outline doesn't include larger descendants of inline elements
*** Bug 149695 has been marked as a duplicate of this bug. ***
This has become a pretty big issue for one of our customers, as it affects focus 
rectangles, which are a pretty big deal.

Can anyone give me a suggestion as to what to look at for this?

We are definitely doing the WRONG thing here.
According to the CSS working group, we're doing the RIGHT thing here under CSS2.
 We may not like it, but that's what they've reaffirmed every time I've pushed
on the point (which has been more than once).  No other browser does it, but
according to the WG those browsers are wrong and Mozilla is not.  Hopefully
David can find his lenghty explanation, because I'd like to see it...
No, the spec is vaguer about 'outline' than it is for other things.  This is
vaguely related to bug 16051.  See the first paragraph of:

http://www.w3.org/TR/REC-CSS2/ui.html#dynamic-outlines

Some discussions of the topic are at:
http://lists.w3.org/Archives/Public/www-style/1999Jul/0020.html
and the thread following it.  My proposed algorithm was in
http://lists.w3.org/Archives/Public/www-style/1999Jul/0039.html
The n.p.m.layout post I mentioned was
http://groups.google.com/groups?selm=slrn7o8b3v.l4s.dbaron%40ice1.fas.harvard.edu
from which you can get to the rest of the thread.
I'm confused. I read all these, and I see nothing that indicates that 
we are doing it " correctly" 

The anchor is the entire image, so if the image has focus, the focus 
rectangle should be around the entire image.

What exactly is the motivation for not putting the focus rect around 
the entire image? I don't understand.
"the anchor is the entire image" doesn't make sense -- the anchor has a box, and
we're drawing the outline around that box.

Nevertheless, the spec allows us to do something more creative.
> the anchor has a box, and
> we're drawing the outline around that box.

OK, now I am really confused.

When an image is an anchor, I can click anywhere on that image to 
execute the anchor. So I would assume that the anchor consists of the 
entire image.

What we are actually drawing a line around, I have no clue. If you tab 
through the images at:

http://www.kaply.com/work/imgfocus.html

you will see that the focus outlines around those images (representing 
the anchors) seems actually rather random. I can see that sometimes it 
could theoretically be the height of the line, but in some cases, it 
is drawing a box around part of the image that does NOT overlap the 
text rectangle. In some other cases, we just lose the bottom.

Should we be using something other than moz-outline for focus 
rectangles?
> When an image is an anchor, I can click anywhere on that image to 
> execute the anchor. So I would assume that the anchor consists of the 
> entire image.

The anchor is the content tree parent of the image, so it gets a chance to
handle the event from the click on the image, even if that click is outside the
bounds of the anchor.
So do you believe there is a problem here to be fixed?

Or do you believe that focus rectangles on images should just continue to look
like crap?
This issue is one of the reasons it's called '-moz-outline' and not 'outline'.
So yes, on the long run, I'd think we want to fix it to be nicer.
> So yes, on the long run, I'd think we want to fix it to be nicer.

OK, so back to my original question. I have a customer who is refusing to roll 
out the browser because of this problem. It makes tab navigation of their 
intranet look horrible.

Big customer. Huge customer. Largest bank on the planet.

So I would like to make an attempt to fix it.

Any ideas?
Tell them to stick

   /* remove Mozilla's focus rings for links */
   :-moz-any-link:focus { -moz-outline: none; }

...in their site stylesheet.
Doesn't that give them no focus rings?

That breaks accessibility. They want focus and they want it to look correct.
Try adding this after Ian's suggested rule:

   a:focus img {-moz-outline: 1px dotted red;}

...or whatever outline styles you prefer.  That ought to outline the image
itself while not outlining the link itself.
Sorry, I didn't read your original post. If the problem is specifically with
links containing images then yes, they need merely add specific rules for those,
such as:

   /* add focus rings for images inside links */
   :-moz-any-link:focus > img { -moz-outline: inherit; }

However, the best solution would be for us to fix out 'outline' support.
I love you guys. These workarounds look great for now.

Thank you thank you a million times thank you.
OK, this is strange. I think I can get this workable, but I thought I might let 
you know results so you can can give some advice.

This line:

:-moz-any-link:focus { -moz-outline: none; }

Removes focus from everything, except images! But now images get the TOTALLY 
correct focus outline (not the messed up one)

This line:

:-moz-any-link:focus > img { -moz-outline: none; }

Causes images to not have messed up focus lines, but the focus they have is just 
a focus box around where text would be in the image, not the entire image as 
happened with removing focus for everything.

So it appears that the reason focus around images draws incorrect is because it 
is the intersection of two focus boxes!!!!

So the question is, is there anyway to get the results of the first one (correct 
image boxes around images) without getting rid of all focus.

What I am wondering is if there is something besides :focus that draws the box 
around images since that didn't disappear when focus was set to none.

BTW, I was using userContent.css to modify this.

This is AWESOME stuff. I'm going to learn lots more about this subject. Thanks!
> This line:
>
>   :-moz-any-link:focus { -moz-outline: none; }
>
> Removes focus from everything, except images!

To be precise, it prevents any links (<a href> elements, <link> elements, and
XLink elements) from having outlines while they are focussed.


> But now images get the TOTALLY correct focus outline (not the messed up one)

The images still get the focus rings because of the following rule in html.css:

 *|*:-moz-any-link:focus img { -moz-outline: 1px dotted invert; }


> This line:
>
>   :-moz-any-link:focus > img { -moz-outline: none; }
>
> Causes images to not have messed up focus lines

Specifically, it cancels the rule from html.css quoted above, i.e. it removes
the outline from around <img> elements that are immediately within <a href>,
<link> or XLink elements that have the focus.


> but the focus they have is just a focus box around where text would be in the 
> image, not the entire image as happened with removing focus for everything.

In fact, it is the outline you get from just the <a href> element, and has
nothing to do with the image itself.


> So it appears that the reason focus around images draws incorrect is because 
> it is the intersection of two focus boxes!!!!

The reason the focus draws incorrectly is that the outline drawing code does not
take the descendent nodes into account. (This bug.)


> So the question is, is there anyway to get the results of the first one 
> (correct image boxes around images) without getting rid of all focus.

No, because CSS has no way of selecting elements based on their contents.
However, if you the author marks the links from which he wishes to remove the
outline, e.g. with a class:

   <a href="..." class="imglink"><img src="..." alt="..."></a>

...then the following CSS would achieve what you want:

   *|*:-moz-any-link.imglink:focus { -moz-outline: none; }
   *|*:-moz-any-link.imglink:focus img { -moz-outline: 1px dotted invert; }


> What I am wondering is if there is something besides :focus that draws the box 
> around images since that didn't disappear when focus was set to none.

There are many bugs in the outline drawing code, one of which is that outlines
are not always correctly removed. This is one of the many reasons why 'outline'
is currently called '-moz-outline' in Mozilla.
>However, the best solution would be for us to fix out 'outline' support.

I still don't understand how we can "fix" our outline support without changing
the place borders are drawn.  CSS2 clearly states that outlines are drawn just
outside the border edge (section 18.4), so outline shoudl effectively do the
same things borders do-- there may be a pixel's difference in placement, but
that's it.  Unless we change our border placement so it encompasses larger
descendant elements, outlines won't encompass them either.  Did I miss some
nifty way to justify ignoring this part of CSS2?  Or were you actually talking
about "fixing" out '-moz-outline' support?
"The outline is drawn starting just outside the border edge.

Outlines may be non-rectangular. For example, if the element is broken across
several lines, the outline is the minimum outline that encloses all the
element's boxes. In contrast to borders, the outline is not open at the line
box's end or start, but is always fully connected." (CSS2 18.4)

The second paragraph is more specific than the first.

Right; CSS2 is merely saying that the outline shouldn't be inside the border
edge. Maybe that should be made clearer in a revision of the spec.
David, I disagree that what you've quoted (comment 26) covers the case of making
an outline encompass large descendant elements of inline elements in a
non-wrapped line-- or, if you prefer, non-wrapped inline elements-- which this
bug concerns.  I also think you're stretching that second paragraph awfully thin
to get it to cover what you seem to want outlines to do, but borders not to do
(for reasons that continue to elude me).  How would you suggest the outline
should be drawn in this situation:

   <a href="blah" style="font-size: 10px">a heart <img src="heart"
style="height: 20px;"> to you</a>
like in IE:
          ........
          : _  _ :
          :( `' ):
  ........: \  / :.......
  :a heart   \/   to you:
  '''''''''''''''''''''''

Note that CSS3 now has a property to control where the border is drawn (but it
is always rectangular).

If it is not clear that the above is allowed per the spec, then we should take
this opportunity to clarify this issue.
Keywords: css2
Summary: -moz-outline doesn't include larger descendants of inline elements → outline doesn't include larger descendants of inline elements
Whiteboard: [Hixie-P3]
*** Bug 58456 has been marked as a duplicate of this bug. ***
*** Bug 67966 has been marked as a duplicate of this bug. ***
*** Bug 122232 has been marked as a duplicate of this bug. ***
Reconfirmed using FizzillaCFM/2002071208. Using Michael's testcase, tabbing
through the images results in oddly shaped focus rectangles. Setting All/All.
Keywords: testcase
OS: Linux → All
Hardware: PC → All
*** Bug 161237 has been marked as a duplicate of this bug. ***
*** Bug 16051 has been marked as a duplicate of this bug. ***
Blocks: 29566
fails on 2003021808 win 2k
Is there any movement on this bug?
Attached file testcase
note: the current useragent implementations, Opera 7.50 TP 3 and Safari 1.2, 
also have the same bug.
*** Bug 253593 has been marked as a duplicate of this bug. ***
Although bug 253593 was marked a DUP of this, it's only recently since bug
151375 has been fixed that foucs outlines on image links have started showing a
problem.
CSS 2.1 says simply that the outline "may be drawn starting just outside the
border edge".

It also says "In contrast to borders, the outline is not open at the line box's
end or start, but is always fully connected if possible." It's not always
reasonable to do that; consider an outlined inline span that starts at the
bottom of one column and continues at the top of the next column.

A quick fix to this immediate problem would be draw outlines around the
*overflow area* of each frame associated with the content. Let me whip up a
patch for that and interested people can try it out and see how they like the
results.

See also bug 24676 for some thoughts about painting outlines. The algorithm I
suggest in bug 24676 comment 36 is compatible with my idea in the previous
paragraph.
This patch extends the outline to the exterior of the frame's overflow area, as
described. Seems to work pretty well.
Attached patch fix (obsolete) — Splinter Review
Hmm, what happened to the patch?
Comment on attachment 154890 [details] [diff] [review]
fix

David, apart from looking at the actual code, I'd appreciate your thoughts
about whether this is the right thing to do at all.
Attachment #154890 - Flags: superreview?(dbaron)
Attachment #154890 - Flags: review?(dbaron)
Shouldn't the fallback behavior in nsIFrame::GetOutlineRect inflate by the
outline width?  Also, I'm not happy about the discontinuity -- when the outline
width changes from 0 to 0.1px, GetOutlineRect changes from the rect to the
overflow area.  That seems like a possible cause for hidden bugs.
Attachment #154890 - Flags: superreview?(dbaron)
Attachment #154890 - Flags: superreview-
Attachment #154890 - Flags: review?(dbaron)
Attachment #154890 - Flags: review-
Attached patch revised patchSplinter Review
OK, this patch addresses those comments. Basically users of GetOutlineRect
should just do GetOverflowRect which always gets the frame's overflow area (or
the frame's size if the frame has no overflow).

This might actually let us simplify the frame invalidation code in response to
style changes in nsCSSFrameConstructor, but we don't need to do that here.
Attachment #154890 - Attachment is obsolete: true
Assignee: dbaron → roc
Attachment #155773 - Flags: superreview?(dbaron)
Attachment #155773 - Flags: review?(dbaron)
Flags: blocking-aviary1.0PR+
Flags: blocking-aviary1.0PR+ → blocking-aviary1.0PR?
I've set the blocking-aviary1.0PR? flag because a recent regression in drawing
of outlines are being duped against this bug. This is a regression since firefox
0.9.
That regression was only on the trunk, not on the Aviary branch, so it did not
affect Firefox 0.9-1.0.
Flags: blocking-aviary1.0PR?
Comment on attachment 155773 [details] [diff] [review]
revised patch

I'm not sure I understand what's making the outline be painted outside of the
overflow area rather than inside it -- although I guess that's the overflow
area computation code somewhere.  But does that code only inflate for the
outline around the frame, or around the whole overflow?
nsIFrame::FinishAndStoreOverflow gets called after Reflow has computed
nsHTMLReflowMetrics::mOverflowArea, which is the union of the overflow areas of
all child frames plus the content area of the current frame.
FinishAndStoreOverflow expands that rectangle with this frame's outline (that
calculation is performed by ComputeOutlineRect). The result is stored as the
frame's new overflow area. nsCSSRendering::PaintOutline paints the outline, if
there is one, on the inside of the frame's overflow area; that is always correct.
Attachment #155773 - Flags: superreview?(dbaron)
Attachment #155773 - Flags: superreview+
Attachment #155773 - Flags: review?(dbaron)
Attachment #155773 - Flags: review+
Status: ASSIGNED → RESOLVED
Closed: 20 years ago
Resolution: --- → FIXED
I think the fixing of this bug causes a bit weird focus rings on
http://www.zeldman.com
Try focusing the top links: "the daily report", "designing with web standards",
etc.

He used a (popular css) technique to hide the original text and instead only
showing the background-image: text-indent: -9999px;
But now Mozilla is drawing the focus rectangle also around the weird
text-indented text.

I'm not sure this is a bug, in fact. But you might want to know this behavior
has changed. 
By the way, IE6 isn't including the text-indented text in the focus rectangle
box.
Interesting. I'm not sure what to do about this.
Not a bug IMHO, although maybe we should split the outline into two boxes in 
cases like these.

(I've long thought the text-indent: -1000px hack to be pretty bogus, btw.)
Yes, sorry, for what it's worth, I too don't think anymore this is a bug in
Mozilla. It's actually better.
The text-indent: -1000px css hack is probably just something temporary which
will be replaced when browser support is there for color:transparent or similar
less hacky than text-indent: -1000px.
Actually, people are waiting for bug 215083 to be supported. This is a
workaround for that. (The problem is that 'content' used in that way is a CSS3
property which is not yet in CR.)
*** Bug 256259 has been marked as a duplicate of this bug. ***
thisbug is back
Referring to Jeffrey Zeldmans test case; Surly this IS a bug! When the outline is applied to an anchor that is in focus surly it is meant to represent the CLICKABLE area of that anchor? 

This bug means that the outline surrounds much more (or less in some cases) than the clickable area. The negative indented text is not part of the clickable area.  Users will expect it to be representative of the clickable area, and so this will lead to confusion in the Firefox user. This is just common sense.
(In reply to comment #59)
> The negative indented text is not part of the
> clickable area.
Actually, it is.
See the "Jeffrey Zeldman testcase". The negative indented text can be clicked upon (also in Opera9. For some reason, IE6 doesn't show the text).
Martijn, that's a fair comment and I admit that I hadn't noticed that. But I still stand by my point because the WHOLE area that gets outlined is not clickable. The text is, sure, but the area between the text and the position of the anchor is not clickable. 

So I would suggest that the solution to be aimed for is probably to have the two separate clickable areas outlined separately. This would solve the problem with websites that use the negative indent to hide text since the outline surrounding the text would also be hidden. 

Thanks though for pointing that out to me! 
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: