Am I missing something, or the behavior of this example — http://dabblet.com/result/gist/1716833 — is rather strange in Webkits/Fx?
There is an input with label and the following selector:
input:hover + .target {
background: red;
}
And this style is triggered when you hover the label
attached to the input
, not only the input
itself. Even more: there is a difference between the label
with for
and input
wrapped in a label
— if you'd hover the input
at first and then move the cursor straight to the .target
— the strange hover won't trigger in wrapped version.
And this is only reproduces in Firefox and Safari/Chrome, but in Opera it's ok.
So, the questions is: if this issue is described somewhere in specs? I couldn't find any appropriate place that describes it and tells what behavior is right.
To remove the CSS hover effect from a specific element, you can set the pointer-events property of the element (the hover behavior of which you want to disable) to “none”.
The :hover CSS pseudo-class matches when the user interacts with an element with a pointing device, but does not necessarily activate it. It is generally triggered when the user hovers over an element with the cursor (mouse pointer).
Definition and Usage The :hover selector is used to select elements when you mouse over them.
The :hover selector is a pseudo-class that allows you to target an element that the cursor or mouse pointer is hovering over. It is difficult to apply the :hover selector on touch devices. Starting in IE4, the :hover selector could only used with <a> tags.
This is in the HTML spec now; it wasn't until the October 2012 WD that it was added to W3C HTML5 (emphasis mine):
The
:hover
pseudo-class is defined to match an element "while the user designates an element with a pointing device". For the purposes of defining the:hover
pseudo-class only, an HTML user agent must consider an element as being one that the user designates if it is:
An element that the user indicates using a pointing device.
An element that has a descendant that the user indicates using a pointing device.
An element that is the labeled control of a
label
element that is currently matching :hover.
Identical text appears in the living spec.
I discovered this very behavior a few years ago on the previous design of my site's contact form, where label:hover
also triggers :hover
on any form input element that is either its descendant or referenced by its for
attribute.
This behavior was actually added to a recent build of Gecko (Firefox's layout engine) in this bug report along with this (rather short) mailing list thread, and it was implemented in WebKit many years back. As you note, the behavior doesn't reproduce in Opera; it looks like Opera Software and Microsoft didn't get the memo.
All I can find in the spec that could relate to this behavior somehow is here, but I don't know for sure (italicized note by me):
- The
:hover
pseudo-class applies while the user designates an element with a pointing device, but does not necessarily activate it. For example, a visual user agent could apply this pseudo-class when the cursor (mouse pointer) hovers over a box generated by the element.[...]
Selectors doesn't define if the parent of an element that is ‘
:active
’ or ‘:hover
’ is also in that state. [It does not appear to define the same for the child of an element either.]Note: If the ‘
:hover
’ state applies to an element because its child is designated by a pointing device, then it's possible for ‘:hover
’ to apply to an element that is not underneath the pointing device.
But what I can conclude is that this behavior is by design in at least Gecko and WebKit.
Regarding what you state here:
Even more: there is a difference between the
label
withfor
andinput
wrapped in alabel
— if you'd hover theinput
at first and then move the cursor straight to the.target
— the strange hover won't trigger in wrapped version.
Given the above behavior, the only possibility left here is that you've simply been bitten by the cascade.
Basically, this rule:
/* 1 type, 1 pseudo-class, 1 class -> specificity = (0, 2, 1) */
input:hover + .target {
background: red;
}
Is more specific than this rule:
/* 1 class, 1 pseudo-class -> specificity = (0, 2, 0) */
.target:hover {
background: lime;
}
So in applicable browsers, the label.target
by your first checkbox will always be red on hover, because the more specific rule always takes precedence. The second checkbox is followed by a span.target
, so none of this behavior applies; only the second rule can take effect while the cursor is over the span.target
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With