Почему IE10 требует наличия правила a p:hover {} для переходов для работы с псевдоэлементом?
HTML:
<p>Hover</p>
CSS:
p::after {
content: " here";
transition: all 1s;
}
p:hover::after {
font-size: 200%;
color: red;
}
Демонстрационная версия: http://jsfiddle.net/SPHzj/13/ (работает в Firefox и Chrome)
Как видите, я настроил CSS-переходы на ::after
псевдоэлемент абзаца. Затем при наведении абзаца на псевдоэлемент, которые переходят, применяются два новых стиля.
Это работает в Firefox и Chrome, но не в IE10. Я рассуждал, что IE не понимает p:hover::after
селектор, как он работает в IE, если вы установите наведение на элемент предка, например div:hover p::after
- живая демонстрация: http://jsfiddle.net/SPHzj/14/.
Однако это не так, поскольку IE действительно способен понять этот селектор. Хитрость заключается в том, чтобы определить p:hover {}
править также. (Обнаружено @ maxw3st.)
p:hover {}
Это правило может быть пустым. Простое наличие этого правила заставит переход работать в IE10.
Демонстрационная версия: http://jsfiddle.net/SPHzj/15/ (также работает в IE10)
Что тут происходит? Почему IE требует, чтобы это правило присутствовало, чтобы переходы работали с псевдоэлементом? Должно ли это быть ошибкой?
3 ответа
Кажется, регрессия
Похоже, что это законный регресс в Internet Explorer 10. Как указано в MSDN, так как пользователи Internet Explorer 7 смогли настроить таргетинг на состояние наведения любого элемента, и не только a
,
Любопытно, что я попробовал :active
псевдокласс, и это, кажется, работает как ожидалось. Далее установив, что это регрессия, вы можете увидеть это, изменив это на a
элемент, переход происходит как ожидалось (так как исторически, a
а также :hover
идти рука об руку).
Опциональные обходные пути
На данный момент я могу придумать лишь несколько решений (в ожидании исправления):
- Используйте пустой
p:hover {}
исправить. - Изменить разметку для цели
::after
на ребенка изp
, - Измените селектор для использования комбинаторов.
Первый пункт - это тот, который вы указали в своем вопросе, и он очень привлекателен, учитывая его простоту. На самом деле, вы могли бы использовать :hover{}
и получить те же результаты ( вероятно, лучшее решение).
Второй пункт также выполним, но немного менее желателен, поскольку требует изменения разметки, что не всегда возможно, и, честно говоря, немного глупо.
Последний вариант несколько интересен. Если вы измените селектор так, чтобы он основывался на родственных отношениях, он волшебным образом снова начнет работать. Например, предположим, у нас есть несколько элементов в теле:
<h1>Hello, World</h1>
<p>This is my first paragraph. it does not animate.</p>
<p>This animates, with a pseudo-element.</p>
Теперь мы можем использовать комбинаторы для нацеливания на второй абзац:
p+p:hover::after {}
Этот селектор будет соответствовать любому абзацу после абзаца, что нежелательно. На данный момент мы могли бы рассмотреть :nth-child
, или же :nth-of-type
чтобы дополнительно указать, какой абзац мы хотим, даже используя общий братский комбинатор:
h1~p:nth-of-type(2):hover::after {} /* Targets second <p> nearest <h1> */
Но в идеале мы бы выбрали цель:
h1~.hoverme:hover::after {} /* Targets <p class="hoverme"> */
Решение с двумя символами?
Еще один шаг, может быть, вы не хотите, чтобы вас явно блокировали, предоставляя общий тэг. Вы также можете использовать универсальный селектор:
*~.hoverme:hover::after {} /* Targets <p class="hoverme"> among siblings */
Это требует, чтобы p
У тега есть родные братья, что обычно и ожидается. Очень редко документ состоит только из одного тега абзаца.
Я понимаю, что они не идеальны, но на данный момент они являются средством для достижения цели. Будем надеяться, что это будет решено в будущих выпусках Internet Explorer.
Как ни странно, эффект будет работать с ссылкой, а не с тегом абзаца.
Это, безусловно, ошибка IE10 или регрессия. К счастью, вы нашли хорошее решение.
Это же явление всплыло, когда я попытался добавить правило для изменения курсора на указатель. Тем не мение,
cursor: pointer;
должен быть включен в родительский псевдо, он не может быть использован для нацеливания только на строку содержимого псевдо в IE10.http://jsfiddle.net/maxw3st/SPHzj/22/ использует div в качестве контейнера, http://jsfiddle.net/maxw3st/7sBVC/ использует обходной путь p:hover. Добавление div было предложено @simevidas, и отлично работает для перехода, только не указатель. Указатель появляется только в IE10, когда он применяется к родительскому элементу псевдоэлемента.