标签:hover属性在IE10和IE11中触发不正确的元素 [英] Label :hover attribute triggers incorrect element in IE10 and IE11
问题描述
这有点奇怪,但是忍受我。这只会影响IE10和IE11,不会影响Chrome,FF,Safari和IE9及更早版本。如果你有一个< label>
用于嵌套在:hover
将匹配该选择器,即使您不是悬停在该元素。在下面的示例中,如果您将鼠标悬停在第一个 div
上,则会突出显示 divs
。
< div>
< select id =min-price>
< option> A< / option>
< / select>
< / div>
< div>
< label for =min-price>< / label>
< select>
< option> B< / option>
< / select>
< / div>
和此CSS:
div {
padding:1em;
margin-bottom:1em;
border-bottom:1px solid red;
}
div:hover {
background:#f1f1f1;
}
div:hover>选择{
background-color:#a3a3a3;
}
示例可以在这里找到。
http://jsfiddle.net/0c67oew2/3/
任何人都解释为什么会发生这种情况?
你读这个答案,我是一个工程师在Internet Explorer团队。
首先,这是一个真的酷发现。你偶然发现的是Internet Explorer的功能(很可能是一个错误),它在Chrome或Firefox中似乎不存在。让我尝试分析一下对发生的情况的理解,为什么这是很酷的,以及你可以做些什么来避免它的并发症:
标签和输入元素可以通过标签
上的 [for]
属性变为内在相关,指向
属性。因此,当您单击标签时,它可以切换复选框,或将焦点应用于输入字段。 输入
元素上的[id]
在相关注意事项中,当您悬停超过 label
,相关的输入
元素也被悬停。这是Internet Explorer,Firefox,Chrome和所有其他人的情况。但是Internet Explorer的不同之处是应用悬停双向。因此,如果您悬停相关的输入
控制,Internet Explorer 也会调用:hover
标签。
这是事情变得酷。这允许我们创建如下所示的关系:
请注意,关系是双向的,意味着任何悬停在输入
不仅仅是一个悬停在自己和它的祖先树上,而且悬停在其相关的标签
上。任何悬停在标签
上的鼠标悬停在其本身,其祖先树及其相关联的输入
上。
当你悬停一个元素时,你会覆盖
em>其父母。例如,假设我们有一个 div
,其中有一个按钮
。任何悬停在按钮
本身就是一个悬浮在父 div
以及。你不能得到的孩子没有先通过父母,只要光标。同样的规则适用于此; 在你的演示中,你有一系列的 div
元素与选择
元素和标签
元素。您将基于父 div
的悬浮伪类的 select
元素的样式。因此,当您悬停 select
时,它会调用其相关联的标签
的悬停,其影响任何嵌套选择
后续建议
虽然 [for]
属性允许您放置标签
在任何地方,你应该继续这样做只有特别意识到这将如何影响选择器操作:hover
传播祖先树。
在给出完整的解决方案之前,我必须问为什么你在一个看似任意的位置放置空标签。你想实现什么视觉效果?我怀疑我们可以用不同的标记完成相同的视觉布局。
从这里继续
我将在我们的内部数据库中打开一个针对此问题的错误,因为我觉得这不是我们完全有意的。我相信,我们的目标是双向处理同样的行为,而不是不同地处理两条路线。
This is a little weird, but bear with me. This only affects IE10 and IE11, doesn't affect Chrome, FF, Safari, and IE9 and older. If you have a <label>
for another element nested within a class that the :hover
is assigned to, it will match that selector, even if you are not hovering over that element. In the example below, if you hover over the first div
, both divs
are highlighted.
<div>
<select id="min-price">
<option>A</option>
</select>
</div>
<div>
<label for="min-price"></label>
<select>
<option>B</option>
</select>
</div>
and this CSS:
div {
padding: 1em;
margin-bottom: 1em;
border-bottom: 1px solid red;
}
div:hover {
background: #f1f1f1;
}
div:hover > select {
background-color: #a3a3a3;
}
Example can be found here.
http://jsfiddle.net/0c67oew2/3/
Any anyone explain why this is happening?
I'm going to note before you read this answer that I am an engineer on the Internet Explorer team.
First of all, this is a really cool discovery. What you've stumbled upon is actually a "feature" (quite possibly a bug) of Internet Explorer that doesn't appear to exist in Chrome or Firefox. Let me try to break down an understanding of what is happening, why this is kind of cool, and what you can do to avoid complications with it:
Labels and input elements can become intrinsically related by way of the [for]
attribute on a label
pointing to the [id]
attribute on an input
element. As a result, when you click on a label, it can toggle a checkbox, or apply focus to an input field. This feature is often times leveraged to create progressively-enhanced radio buttons and more.
On a related note, when you hover over a label
, the associated input
element is also hovered. This is the case with Internet Explorer, Firefox, Chrome, and just about everybody else. But what Internet Explorer does differently is apply the hover bi-directional. So if you hover the associated input
control, Internet Explorer also invokes :hover
on the related label
.
This is where things get cool. This allows us to create relationships like the one seen below:
Note here that the relationship is bi-directional, meaning any hover on an input
is not simply a hover on itself and its ancestral tree, but also a hover on its associated label
. And any hover on a label
is a hover on itself, its ancestral tree, and its associated input
. This brings us one step closer to understanding what's at play in your demo, and why you're seeing such bizarre results.
When you hover an element, you are covering its parents too. As an example, suppose we had a div
with a button
inside of it. Any hover on the button
is inherently a hover on the parent div
as well. You can't get to the children without first going through the parents as far as a cursor is concerned. The same rule applies here; when a label or input is hovered, so too are its parents.
In your demo you have a series of div
elements with select
elements and label
elements inside. You're basing styles for the select
elements on the hover pseudo-class of their parent div
. So when you hover the select
, it invokes the hover of its associated label
, which causes the hover of its parent, which affects the styles of any nested select
.
Subsequent Suggestion
While the [for]
attribute allows you to place label
elements just about anywhere, you should proceed in doing so only with special awareness to how this will affect selectors operating off of :hover
propagation up the ancestral tree.
Before a complete solution can be given, I must ask why you are putting an empty label in a seemingly arbitrary location in the first place. What visual effect are you trying to achieve? I suspect we could accomplish the same visual layout with different markup.
Following Up from Here
I'm going to open a bug against this in our Internal database, because I get the feeling that this isn't entirely intentional on our part. Our aim, I believe, is to treat the behavior the same bi-directionally, rather than handling the two routes differently.
这篇关于标签:hover属性在IE10和IE11中触发不正确的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!