Почему при наведении указывается на соответствующем ярлыке в CSS? - PullRequest
13 голосов
/ 01 февраля 2012

Я что-то упустил, или поведение этого примера - http://dabblet.com/result/gist/1716833 - довольно странно в Webkits / Fx?

Есть вход с меткой и следующим селектором:

input:hover + .target {
    background: red;
}

И этот стиль срабатывает, когда вы наводите label, прикрепленный к input, а не только к input.Еще больше: есть разница между label с for и input, завернутыми в label - если вы сначала наведите input, а затем переместите курсор прямо к .target -странный зависание не будет срабатывать в упакованной версии.

И это воспроизводится только в Firefox и Safari / Chrome, но в Opera все нормально.

Итак, вопросы: если эта проблемаописано где-то в спецификации?Я не смог найти подходящего места, которое бы описывало его и говорило, какое поведение правильное.

1 Ответ

12 голосов
/ 01 февраля 2012

Это сейчас в спецификации HTML; Лишь в октябре 2012 года WD был добавлен в W3C HTML5 (выделено мое):

Псевдокласс :hover определен для соответствия элементу "в то время как пользователь обозначает элемент с указательным устройством". В целях определения только псевдокласса :hover пользовательский агент HTML должен рассматривать элемент как элемент, который пользователь назначает , если это:

  • Элемент, который пользователь указывает с помощью указывающего устройства.

  • Элемент с потомком, который пользователь указывает с помощью указывающего устройства.

  • Элемент, помеченный как элемент управления label элемента, который в данный момент соответствует: hover.

Идентичный текст появляется в живой спецификации .


Я обнаружил такое же поведение несколько лет назад в предыдущем дизайне контактной формы моего сайта, где label:hover также запускает :hover на любом элементе ввода формы, который является либо его потомком, либо на него ссылается его атрибут for.

Это поведение было фактически добавлено к недавней сборке Gecko (движка разметки Firefox) в этом отчете об ошибках вместе с этой (довольно короткой) веткой списка рассылки , и оно было реализовано в WebKit много лет назад . Как вы заметили, поведение не воспроизводится в Opera; похоже, что Opera Software и Microsoft не получили памятку.

Все, что я могу найти в спецификации, что может как-то относиться к этому поведению, это здесь , но я точно не знаю (выделенный мной курсивом):

  • Псевдокласс :hover применяется, когда пользователь назначает элемент с указательным устройством, но не обязательно его активирует. Например, визуальный пользовательский агент может применить этот псевдокласс, когда курсор (указатель мыши) находится над блоком, сгенерированным элементом.

[...]

Селекторы не определяют, находится ли родительский элемент элемента ":active" или ":hover" также в этом состоянии. [По-видимому, он также не определяет то же самое для дочернего элемента.]

Примечание: Если состояние «:hover» применяется к элементу, поскольку его дочерний элемент обозначен указательным устройством, то «1076 *» может применяться к элементу, который не является под указательным устройством.

Но я могу сделать вывод, что такое поведение предусмотрено, по крайней мере, в Gecko и WebKit.


Относительно того, что вы здесь указали:

Еще больше: есть разница между label с for и input, заключенными в label - если вы сначала наведите input, а затем переместите курсор прямо к .target - в завернутой версии странный зависание не сработает.

Учитывая вышеупомянутое поведение, единственная оставленная здесь возможность состоит в том, что вас просто укусил каскад.

В основном это правило:

/* 1 type, 1 pseudo-class, 1 class -> specificity = (0, 2, 1) */
input:hover + .target {
    background: red;
}

Более конкретно, чем это правило:

/* 1 class, 1 pseudo-class         -> specificity = (0, 2, 0) */
.target:hover {
    background: lime;
}

Таким образом, в применимых браузерах label.target в вашем первом флажке всегда будет красным при наведении, потому что более конкретное правило всегда имеет приоритет. За вторым флажком следует span.target, поэтому ни одно из этих действий не применимо; только второе правило может действовать, пока курсор находится над span.target.

...