Closed Bug 302561 Opened 20 years ago Closed 16 years ago

:hover styles that move/resize element cause endless reflow oscillation

Categories

(Core :: Layout, defect)

defect
Not set
normal

Tracking

()

VERIFIED FIXED
mozilla1.9.1b3

People

(Reporter: shane, Assigned: dbaron)

References

()

Details

(Keywords: regression, testcase, verified1.9.1)

Attachments

(5 files, 3 obsolete files)

User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/412+ (KHTML, like Gecko) Safari/412.2 Build Identifier: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.8b4) Gecko/20050718 Firefox/1.0+ If the border of an element is specified to be null when hovered over, then hovering over the border causes the element and border to blink rapidly. Reproducible: Always Steps to Reproduce: 1. Open specified URL 2. Hover mouse pointer over the border that underlines XHTML 3. Actual Results: Element and border blink rapidly. I think what's happening is that, when hovering over the border, it disappears, disabling it from being hovered over, whereby it reappears, and can then be hovered over again, thereby repeating and thus the blinking. Expected Results: Element and border should not blink. Hovering over the border should disable it from being displayed.
I was only able to test this on recent builds of Camino and Firefox for Mac OS X.
Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.8b4) Gecko/20050729 Firefox/1.0+ ID:2005072903 I see the described behaviour too.
Keywords: testcase
Status: UNCONFIRMED → NEW
Ever confirmed: true
OS: MacOS X → All
Hardware: Macintosh → All
*** Bug 304604 has been marked as a duplicate of this bug. ***
I'm not sure, but is this is another case of this bug: http://www.croczilla.com/svg/samples/opacity2/opacity2.svg Put your mouse in the middle of the star, and move it in a diagonal movement to the top-right. When the mouse nears the green hexagon the red stroke line is lost around the star (it flashes as the mouse movement). Try it a couple of times (move the mouse to different places, around the border of the hexagon if you can't succeed.
This is the right behavior, and you described it exactly in comment 0. I don't know where your "Hovering over the border should disable it from being displayed." expected result comes from -- once there is no border, the element is not in :hover anymore, as you noted.
Status: NEW → RESOLVED
Closed: 19 years ago
Resolution: --- → INVALID
(In reply to comment #6) > This is the right behavior, and you described it exactly in comment 0. I don't > know where your "Hovering over the border should disable it from being > displayed." expected result comes from -- once there is no border, the element > is not in :hover anymore, as you noted. Right, but the problem is that the border _doesn't_ go away completely. When the border itself is hovered over (note: not the rest of the element, just the border itself), it dissappears and reappears rapidly, like a strobe light. If that _is_ the desired behavior, it certainly is strange.
This makes it a little easier to position the mouse pointer over the element's border so the bug is a little more obvious.
Technically, Gecko's behaviour is correct: as soon as you hover over the border, the border disappears, but then the inline-box shrinks and the pointer is out of the 'hovered' area, hence the border reappears. Opera 9 preview and Safari do the same thing, although more slowly. If I were to use this in a stylesheet, I would only change the color of the border (to match the background-colour) on :hover, or add padding to match the width of the border.
> that the border _doesn't_ go away completely Sure it does. It goes away. The element's size changes. The element is no longer hovered. The :hover style no longer applies. There is a border again. And so forth. Let's put this another way. What do YOU think is the correct layout here? And why is it correct?
I do realize that Gecko is doing what it is technically supposed to be doing, and maybe the W3C spec actually does call for this to happen (although I haven't read the spec in full). I'm just saying that the behavior is strange. Imagine, for example, that you have a hyperlink that is styled with a bottom border that will be removed on :hover. Naturally, when you mouse over that link, you expect the cursor to change to a hand and the border to dissapear. You do not expect to have the cursor flip rapidly back and forth between a pointer and a hand and to have the border flash on and off the screen. I've seen cases where this has made the entire page jiggle up and down when the cursor is at rest in one spot. Ideally, when a web developer styles content to remove a border on hover, I believe there should be a definite hover "zone" and a definite non-hover "zone" and no interim area in which an element can be both hovered and not hovered when the cursor stays in the same spot (which kind of defies reason). I know what Gecko's logic is here. All I'm saying is that its behavior, however intentional it may be in this instance, is a major, major annoyance.
> and maybe the W3C spec actually does call for this to happen It does, though it has weasel-language about it being OK to change layout on hover (which means that in this testcase :hover would have absolutely no effect on that node in a UA that takes that way out). > although I haven't read the spec in full I highly recommend doing that before arguing about spec-compliance issues... What is your definition of "hover" exactly, in the face of elements changing size? I don't see a self-consistent way to define hover that satisfies your conditions, but if you do, please enlighten me. > is a major, major annoyance. If you have issues with the CSS spec, I suggest taking it up with www-style@w3.org. Please do make sure you have a proposal for how things should work in this case if you do that, though (that would be the definition I mention above).
The issue here is that the spec (correct me if I'm wrong) requires that the border be part of the element, which, in and of itself, makes sense. However, if the border weren't part of the element, then hovering over it (the border) wouldn't cause it (the border) to be removed like it is now, thus fixing the problem we're having. Since this is a pretty nebulous spec issue, I believe I will take this up with the W3C, as you suggested. I'll post here again if I get some sort of response.
> requires that the border be part of the element The spec doesn't define what constitutes :hover, actually. Gecko treats it as "hover over the border-box". Any such definition has a problem if you change the relevant dimensions in :hover, though. Even if we defined it to be the content-box, you would get flicker with the testcase if you moved your mouse in a little from the border.
* This bug breaks compatibility with IE7, Safari3b, Opera9. * This is a regression against 1.7.5 (FF 1.0) Perhaps it's worth to consider reopening. IE supports :hover on any Element now. See related bug 389695 (came up in the forums). j.j.
> * This bug breaks compatibility with IE7, Safari3b, Opera9. What exactly do those UAs do differently from us?
(In reply to comment #16) > What exactly do those UAs do differently from us? attachment (id=275692) (cross-browser testcase) Move cursor over the red bar and stay there- red bar flickers on and off permanently with currenent trunk no flickering with other browsers, including FF 1.0 http://jeka.info/test/jump.htm (testcase from bug 389695 comment 3) Move cursor over the arrows and stay there- content flickers and jumps around permanently with current trunk no flickering and jumping with other browsers incl. FF 1.0 (Note: This bug is about borders, bug 389695 is about margins and paddings) j.j.
> Move cursor over the red bar and stay there- > red bar flickers on and off permanently with currenent trunk That's not the behavior I see (on Linux). The bar is either on or off depending on whether I moved into it from above or below. But in any case, this doesn't answer my question. I wasn't asking what the testcase looks like in other UAs. I was asking _why_ it looks like it does. That is, exactly what they do differently. If we're going to claim there's incompatible behavior, then data is needed on exactly what aspects are incompatible.
> That's not the behavior I see (on Linux). I did all my tests on winXP. Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9a8pre) Gecko/2007080705 Minefield/3.0a8pre
That's fine. My question remains, however.
(In reply to comment #16) > > * This bug breaks compatibility with IE7, Safari3b, Opera9. > > What exactly do those UAs do differently from us? Boris, I'm not exactly sure what you mean, seems obvious: The :hover pseudo-class applies if 1. the cursor is located over the box and 2. the cursor is moving at the same time. The :hover style releases if 1. the cursor is not located over the box (or the box isn't displayed at all) and 2. the curser is moving. (Not if it remains stationary) The last point makes the difference in Gecko. Does this answer your question? (In reply to comment #19) > That's not the behavior I see (on Linux). The bar is either on or off > depending on whether I moved into it from above or below. Test on Windows (attachment 275692 [details]). [ Sorry, this bugged me several times in browsing and recently by toying with -moz-transform. We need this fixed, or at least considered to be a valid bug. (This is also a regression against Gecko 1.7.5). Should I file a new bug regarding -moz-transform ? ]
Keywords: regression
That we go out of :hover when the page moves for other reasons is a feature. That we oscillate is a bug; I wrote code to prevent us from oscillating when we added that feature.
Status: RESOLVED → REOPENED
Resolution: INVALID → ---
My guess is that the code to prevent this in nsViewManager::ProcessSynthMouseMoveEvent and nsViewManager::SynthesizeMouseMove stopped working either (1) when we started processing style changes asynchronously or (2) when it was rewritten in the thread manager landing.
Summary: element with border blinks repeatedly when hovering over border removed via :hover → :hover styles that move/resize element cause endless reflow oscillation
Assignee: nobody → dbaron
Status: REOPENED → ASSIGNED
Attached patch patch (obsolete) — Splinter Review
Here's a patch that I think gets us back to the old behavior of a single flicker per mouse move when in one of these bad regions of the page. I haven't tested it much yet, and I still need to think about writing some automated tests.
Attached patch patch (obsolete) — Splinter Review
I'm giving up on the test for now; I may come back to it. I actually am getting the resize events as a result of the synthesized mouse moves. However, I'm always getting the non-:hover style. This causes the test to stop running at step3, where the coalescing check fails even though it should pass. I need to figure out why, at some point.
Attachment #349590 - Attachment is obsolete: true
> The :hover pseudo-class applies if > 1. the cursor is located over the box > and 2. the cursor is moving at the same time. A bit of testing shows this to not beat all correct. For example, scrolling the page (with mousewheel or keyboard) such that the motionless mouse cursor ends up over an element brings that element into hover in Opera and Safari. Using a JS setTimeout to position an element under the cursor doesn't put it into hover immediately, but puts it into hover if the mouse is clicked without moving (easy with a trackpad) in all of Opera, Safari, and IE. It also puts it into hover if any keyboard event happens in Safari. Hovering over the border in the testcases in this bug and hitting the "shift" key over and over again is an exercise worth doing in Safari. This is Opera/Safari on Mac, IE7 on Windows.
Attached patch patch (obsolete) — Splinter Review
I finally got the test working (debugging the problems was a bit of a pain: the main problem was that I need to wait for paint suppression to be over; then I discovered that I was sending events relative to divtwo instead of relative to divtwoparent).
Attachment #349597 - Attachment is obsolete: true
Attachment #349845 - Flags: superreview?(bzbarsky)
Attachment #349845 - Flags: review?(bzbarsky)
Attachment #349845 - Flags: superreview?(bzbarsky)
Attachment #349845 - Flags: superreview+
Attachment #349845 - Flags: review?(bzbarsky)
Attachment #349845 - Flags: review+
Attached patch patchSplinter Review
So it turns out that last time, the test worked fine on its own, but it didn't when it was in an iframe. I started off thinking it was a problem with the test, but then realized it was a problem with the code. This fixes said problem in nsViewManager.cpp, by changing which PresShell we send the synth mouse move event through. I'm asking roc to review this time because of the new changes. I had to write a FindViewContaining method, which is only used when FindFloatingViewContaining comes up empty. I think the assumptions it's making about views containing each other should be correct for non-folating views, but I'd like roc to check that. It would be nice if there were a pre-existing way to do this, but I didn't find one. I also changed FindFloatingViewContaining to use GetViewVisibility rather than IsViewVisible. The only difference is that IsViewVisible walks up the view's parent chain; instead we can just cut off the recursion with GetViewVisibility. The only functional difference should be the call to the view observer, which should only differ in the case where we're inside a hidden tab, which should never be the case if we've got the mouse position. Does this seem like a reasonable approach?
Attachment #349845 - Attachment is obsolete: true
Attachment #351261 - Flags: superreview?(roc)
Attachment #351261 - Flags: review?(roc)
Attachment #351261 - Flags: superreview?(roc)
Attachment #351261 - Flags: superreview+
Attachment #351261 - Flags: review?(roc)
Attachment #351261 - Flags: review+
There were crashes in chrome/browser tests related to menus. This fixes them. It applies on top of attachment 351261 [details] [diff] [review].
Attachment #351424 - Flags: superreview?(roc)
Attachment #351424 - Flags: review?(roc)
Attachment #351424 - Flags: superreview?(roc)
Attachment #351424 - Flags: superreview+
Attachment #351424 - Flags: review?(roc)
Attachment #351424 - Flags: review+
Status: ASSIGNED → RESOLVED
Closed: 19 years ago16 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla1.9.2a1
Were you planning to land this in 1.9.1? If so, don't forget to land 468753 with it.
Depends on: 468753
Flags: blocking1.9.1?
I was not planning to land this in 1.9.1. sgautherie: Why did you nominate it for blocking?
Because it's an bothersome bug and a forgotten regression which should be fixed? Should be "wanted1.9.1" IMHO. Is there any reason not to land this in 1.9.1 ?
(In reply to comment #37) > sgautherie: Why did you nominate it for blocking? In support of comment 36, to sort out if both or none of these 2 bugs should actually block. *** [Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.9.2a1pre) Gecko/20081212 Minefield/3.2a1pre] (nightly) (W2Ksp4) Additionally, I hoped this might fix a similar "disturbing" behavior an (old / "MsIE-designed") (restricted access) site I'm using has, but it doesn't :-|
Comment on attachment 351261 [details] [diff] [review] patch OK, I suppose this is relatively straightforward and it does fix a pretty nasty bug that can prevent users from being able to do things like click on links. I'll make sure to land the followup fixes along with it.
Attachment #351261 - Flags: approval1.9.1?
Comment on attachment 351261 [details] [diff] [review] patch a191=beltzner
Attachment #351261 - Flags: approval1.9.1? → approval1.9.1+
Keywords: fixed1.9.1
Target Milestone: mozilla1.9.2a1 → mozilla1.9.1b3
Flags: in-testsuite+
Flags: blocking1.9.1? → wanted1.9.1+
Verified fix on Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20090130 Shiretoko/3.1b3pre Ubiquity/0.1.5 and Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.2a1pre) Gecko/20090130 Minefield/3.2a1pre
Status: RESOLVED → VERIFIED
Depends on: 507006
No longer depends on: 507006
Blocks: 683939
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: