Метка: атрибут 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;
}
Другие вопросы по тегам