Метка: атрибут hover вызывает некорректный элемент в IE10 и 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 > select {
background-color: #a3a3a3;
}
Пример можно найти здесь.
http://jsfiddle.net/0c67oew2/3/
Кто-нибудь объяснит, почему это происходит?
2 ответа
Прежде чем прочитать этот ответ, я отмечу, что я инженер в команде Internet Explorer.
Прежде всего, это действительно классное открытие. На что вы наткнулись - это на самом деле "особенность" (вполне возможно, ошибка) Internet Explorer, которой, по-видимому, нет в Chrome или Firefox. Позвольте мне попытаться сломать понимание того, что происходит, почему это круто, и что вы можете сделать, чтобы избежать осложнений:
Метки и элементы ввода могут стать неразрывно связанными посредством [for]
атрибут на label
указывая на [id]
атрибут на input
элемент. В результате, когда вы нажимаете на метку, она может установить флажок или применить фокус к полю ввода. Эту функцию часто используют для создания прогрессивно улучшенных переключателей и многого другого.
С другой стороны, когда вы наводите курсор на label
, связанный input
элемент тоже завис. Это касается Internet Explorer, Firefox, Chrome и почти всех остальных. Но то, что Internet Explorer делает по-другому - это применение двунаправленного наведения. Так что, если вы наводите input
Internet Explorer также вызывает :hover
на связанных label
,
Здесь все становится круче. Это позволяет нам создавать отношения как показано ниже:
Обратите внимание, что эти отношения являются двунаправленными, что означает input
это не просто зависание над собой и своим исконным деревом, но и зависание над связанным с ним label
, И любой завис на label
является парением над собой, своим исконным деревом и связанным с ним input
, Это делает нас на один шаг ближе к пониманию того, что играет в вашей демонстрации, и почему вы видите такие странные результаты.
Когда вы наводите элемент, вы также скрываете его родителей. В качестве примера, предположим, у нас был div
с button
внутри него. Любое зависание на button
по своей сути парение над родителем div
также. Вы не можете добраться до детей, не пройдя сначала через родителей в том, что касается курсора. То же правило применяется здесь; когда метка или входные данные находятся наверху, то же самое происходит и с их родителями.
В вашей демоверсии у вас есть серия div
элементы с select
элементы и label
элементы внутри. Вы основываете стили для select
элементы на псевдокласс класса своего родителя div
, Поэтому, когда вы наводите select
, он вызывает зависание своей связанной label
, который вызывает зависание своего родителя, что влияет на стили любого вложенного select
,
Последующее предложение
В то время как [for]
атрибут позволяет размещать label
элементы почти везде, вы должны продолжать делать это только с осознанием того, как это повлияет на селекторы, работающие от :hover
распространение по наследственному дереву.
Прежде чем дать полное решение, я должен спросить, почему вы помещаете пустой ярлык в, казалось бы, произвольное место. Какой визуальный эффект вы пытаетесь достичь? Я подозреваю, что мы могли бы сделать один и тот же визуальный макет с другой разметкой.
Следуя отсюда
Я собираюсь открыть ошибку в нашей внутренней базе данных, потому что у меня такое ощущение, что это не совсем намеренно с нашей стороны. Я считаю, что наша цель состоит в том, чтобы относиться к поведению одинаково в двух направлениях, а не обрабатывать два маршрута по-разному.
Я рекомендую использовать:focus вместо:hover при работе с входными данными формы. Одна из причин этого заключается в том, что если пользователь перемещается по клавиатуре, наведение не будет ничего делать, а фокус будет.
.control .price:focus {
background: #a3a3a3;
}