Почему .foo a: link,.foo a: visited {} селектор переопределяет: hover, a: active {} селектор в CSS?
Пример кода: http://jsfiddle.net/RuQNP/
<!DOCTYPE html>
<html>
<head>
<title>Foo</title>
<style type="text/css">
a:link, a:visited {
color: blue;
}
a:hover, a:active {
color: red;
}
.foo a:link, .foo a:visited {
color: green;
}
/* A possible fix */
/*
.foo a:hover, .foo a:active {
color: red;
}
*/
</style>
</head>
<body>
<div class="foo">
<a href="#" onclick="location.href='http://example.com/'; return false;">Example</a>
</div>
</body>
</html>
Что я ожидал:
Ссылка будет отображаться красным при наведении.
Что я получаю:
Ссылка отображается зеленым при наведении.
Вопросы:
- Почему
color
, определенный в .foo a:link, .foo a:visited
селектор переопределяет значение в a:hover, a:active
? Что происходит?
- Я понимаю, что могу исправить это и получить то, что ожидаю, раскомментируя
прокомментированный код. Однако я хочу знать, как мы можем исправить
.foo a:link, .foo a:visited
, чтобы он не
переопределить color
, определенный в a:hover, a:active
?
Если я правильно понимаю http://www.w3.org/TR/CSS21/cascade.html#specificity (спасибо, BoltClock), это таблица спецификаций для различных селекторов в коде.
a:link - 0 0 1 1
a:visited - 0 0 1 1
a:hover - 0 0 1 1
a:active - 0 0 1 1
.foo a:link - 0 0 2 1
.foo a:visited - 0 0 2 1
Таким образом, стиль, определенный для .foo a:link
, переопределяет стиль для a:hover
, когда как link
, так и hover
псевдоклассы применяются к элементу класса класса foo
.
Аналогично, стиль, определенный для .foo a:visited
, переопределяет стиль для a:hover
, когда как visited
, так и hover
псевдоклассы применяются к элементу класса класса foo
.
Ответы
Ответ 1
Когда вы впервые начали использовать CSS, вы могли бы узнать о мнемонике LoVe-HAte для того, чтобы указать, какие селектора ссылок (a:link
, a:visited
, a:hover
, a:active
). Вы когда-нибудь задумывались, почему эта мнемоника была выбрана?
Хорошо, там есть примечание в spec о том, как обрабатываются ссылки и динамические псевдоклассы, когда к ним применяются несколько правил, использующих все из них тот же элемент, который объясняет, почему вам нужно установить селектор каналов в следующем порядке:
Обратите внимание, что A: hover должен быть размещен после правил A: link и A: visited, так как в противном случае каскадные правила скроют свойство "color" правила A: hover. Аналогично, поскольку A: активный помещается после A: hover, активный цвет (известь) будет применяться, когда пользователь активирует и навешивает над элементом A.
Во всяком случае, точка, которую я пытаюсь сделать выше, состоит в том, что все четыре псевдокласса, будучи псевдоклассами, имеют одинаковую специфичность. Все, что касается специфики, применяется. В этом случае из группы одинаково определенных селекторов применяется последнее правило. Когда и как запускается каждый псевдокласс, это никогда не актуально.
Теперь простое введение селектора .foo
приводит к тому, что ваш второй набор правил ссылок/посещений переопределяет ваш первый набор стилей ссылок/посещений и стилей hover/active, заставляя ссылки в элементы с этим классом всегда будут зелеными, пока вы не добавите наведение/активные стили с помощью селектора .foo
.
Извините, если мой ответ кажется сшитым или slipshod, кстати, я набираю это на своем iPhone прямо сейчас, и это довольно сложно придумать здесь...
Ответ 2
Вот как я это понимаю. Все эти псевдо классы имеют одинаковую специфичность, поэтому, наконец, побеждает псевдокласс. Теперь, что делают псевдоклассы :link, :visited, :focus, :hover, :active
? Давайте посмотрим один за другим.
a: link{color: red}
указывает агенту пользователя окрасить элемент привязки красным цветом в любое состояние. Выполните следующие script:
a:link {
color: red;
}
<a href="www.stackoverflow.com">Go to stackoverflow </a>
Ответ 3
Чтобы исправить это, сначала поставьте селектор .foo ...
и добавьте !important
в значение цвета для другого селектора ссылок/посещений, например:
a:link, a:visited {
color: blue;
}
a:hover, a:active {
color: red !important;
}
.foo a:link, .foo a:visited {
color: green;
}
Причина, по которой селектор .foo a:link, .foo a:visited
переопределяет другой селектор, независимо от того, где вы его помещаете, состоит в том, что, поскольку .foo a:link
более определен, чем a:link
. (так же для :visited
.) Таким образом, селектор .foo ...
всегда будет переопределять селектор a:link,a:visited
, потому что он имеет имя родительского класса, поэтому он более конкретный.
(Также читайте @BoltClock ответ о LoVe - HAte - той части проблемы.)