Ответ 1
Это, конечно, предполагает, что никогда не будет использовать тег
<a>
без значенияhref
. Возможно, это ошибочное предположение.
Ну, на самом деле... не каждый элемент <a>
должен иметь атрибут href
. В самом деле, он еще не требовал в HTML5, чтобы указать href
для каждого <a>
. Chris Blake и Ryan P рассказывают о концепции именованных якорей, и я добавлю, что пока name
для <a>
был сделанный устаревшим с HTML5, названные якоря по-прежнему распространены и будут по-прежнему распространяться просто по наследству и традиция.
Тем не менее, в будущем, авторам рекомендуется использовать атрибуты id
и неменованные якоря для обозначения фрагментов якоря документа.
Кроме того, <a>
элементы, которые не имеют атрибутов href
, но имеют атрибуты onclick
для JavaScript, являются беспорядком. Даже если вы настаиваете на использовании onclick
для привязки событий, для изящного деградации вы должны хотя бы указать его где-нибудь, используя href
.
Но чтобы все было просто, предположим, что вы не будете писать элементы <a>
без атрибутов href
.
С учетом этого, возвращаясь к селекторам CSS, необходимо учитывать два важных момента:
Являются ли они одинаковыми?
Нет, селектора a
и a:link, a:visited
не являются строго эквивалентными. Я приведу предыдущий ответ по этой теме:
Селектор
a
должен соответствовать любым элементам<a>
, тогда какa:link
соответствует только элементам<a>
, которые являются невидимыми гиперссылками (тип документа HTML 4 определяет гиперссылки как элементы<a>
с атрибутомhref
), Нигде он не указывает в любой спецификации, чтоa
должен автоматически перевести наa:link
или наоборот.
Другими словами, в HTML a:link, a:visited
(в CSS1) строго эквивалентен a[href]
(в CSS2 с селектором атрибутов), а не a
. Обратите внимание, что не имеет значения, имеет ли атрибут значение или нет, если оно присутствует, следовательно [href]
. Также обратите внимание, что это верно для всех текущих стандартов HTML, и я считаю, что это включает HTML5, поскольку, как упоминалось выше, href
не является обязательным атрибутом в любой существующей спецификации.
Просто имейте в виду, что другие языки могут определять совершенно разные семантики для :link
и :visited
- это просто так, что они совпадают с одинаково определенным селектором в HTML, который рассматривается далее...
Специфичность
Это огромный результат: a
менее специфичен, чем a:link
или a:visited
, что является очень распространенным источником проблем специфичности, которые особенно очевидны при применении стилей к a
, a:link
и a:visited
отдельно. Это приводит к появлению всех видов хакеров, чтобы обойти недостаток понимания специфичности. 1
К счастью, селектор атрибутов так же специфичен, как и псевдокласс. Это означает, что вы можете использовать a[href]
для обозначения как/либо a:link
, так и/или a:visited
, и не сталкиваться с проблемами специфичности, поскольку они одинаково специфичны!
Например, рассмотрим этот CSS:
/* All unvisited links should be red */
a:link {
color: red;
}
/* All visited links should be slightly darker */
a:visited {
color: maroon;
}
/* But no matter what, header links must be white at all times! */
body > header > a {
color: white;
}
Это работает не так, как ожидалось, потому что a:link
и a:visited
более специфичны, чем body > header > a
, поэтому заголовки заголовков фактически будут никогда белыми:
/* 1 pseudo-class, 1 type -> specificity = (0, 1, 1) */
a:link, a:visited
/* 3 types -> specificity = (0, 0, 3) */
body > header > a
Теперь первое, что приходит в голову большинству CSS-кодеров, заключается в том, чтобы вставить !important
, вообще говоря, специфику перехода:
body > header > a {
color: white !important;
}
Но это дает вам все виды плохой репутации, верно?
Хорошо, если вам неудобно использовать !important
, вы можете использовать a[href]
, как описано выше:
/* 1 attribute, 3 types -> specificity = (0, 1, 3) */
body > header > a[href] {
color: white;
}
Или сделайте это, у которого есть проблема быть многословным, но более дружелюбным к старым браузерам, а также просто более интуитивно понятным:
/* 1 pseudo-class, 3 types -> specificity = (0, 1, 3) */
body > header > a:link, body > header > a:visited {
color: white;
}
Итак, какой селектор использовать?
В конце концов, это все еще безумно субъективно, но я следую этим личным эмпирическим правилам:
-
Применить к
a
стилям, которые не зависят от состояния ссылки (т.е. до тех пор, пока это будет ссылка). -
Применить к стилям
a:link
иa:visited
, где имеет значение, посещена ли ссылка или нет. -
Принимая во внимание упомянутые выше проблемы специфичности, не смешивайте никаких объявлений между правилами
a
иa:link
/a:visited
. Если мне нужно применить одно и то же свойство к обоим состояниям где-то, но у меня уже есть его в отдельных правилахa:link
иa:visited
, напишите селектор, который объединяет оба псевдокласса; не просто используйтеa
!
Например, вот стили ссылок, которые я использую на своем сайте:
a {
text-decoration: none;
transition: text-shadow 0.1s linear;
}
a:link {
color: rgb(119, 255, 221);
}
a:visited {
color: rgb(68, 204, 170);
}
a:hover, a:active {
text-shadow: 0 0 0.5em currentColor;
outline: 0;
}
/* ... */
footer a:link, footer a:visited {
color: rgb(71, 173, 153);
}
Переход text-shadow
определяется для всех элементов a
, независимо от того, были ли они посещены или нет, потому что переход только вступает в силу, когда один из них замаскирован и щелкнут (соответствует правилу a:hover, a:active
),.
Теперь я хочу, чтобы посещенные ссылки имели слегка более темный оттенок, чем невидимые ссылки, поэтому я добавляю цвета в отдельные правила a:link
и a:visited
. Однако по какой-то причине я хочу, чтобы ссылки нижнего колонтитула отображались в том же цвете, независимо от того, посещаются они или нет.
Если я использую footer a
, я столкнусь с проблемами специфичности, описанными выше, поэтому я выбираю footer a:link, footer a:visited
. Я мог бы легко пойти с footer a[href]
, потому что это работает так же хорошо, но я лично предпочитаю указывать оба псевдокласса, потому что он более интуитивно понятен, даже если он делает селектор немного длиннее.
1 Специфичность и повторные селекторы поставили такую огромную проблему, фактически, что рабочая группа выдвинула предложение для :any-link
псевдокласс в следующей спецификации, чтобы избавиться от необходимости полагаться на атрибут href
в HTML, но ему придется подождать long перед тем, как увидеть свет дня (и кто знает, к чему это будет к тому моменту):
/* 1 pseudo-class, 3 types -> specificity = (0, 1, 3) */
body > header > a:any-link {
color: white;
}