В чем разница между html[lang=en] и html:lang(en) в CSS?

Псевдокласс языка CSS, позволяющий указать разные стили для разных языков, например:

html:lang(en) .foo { ... }

Однако это не работает в IE7, поэтому я использовал селектор атрибутов:

html[lang="en"] .foo { ... }

Кажется, они делают одно и то же, но есть ли тонкие различия? А если нет, то почему в CSS вообще есть языковой псевдокласс, если селектор атрибутов делает то же самое?


person john    schedule 18.01.2012    source источник


Ответы (4)


В HTML и псевдокласс :lang(), и селектор атрибутов будут соответствовать элементу с соответствующим атрибутом lang.

Разница в том, что у браузера могут быть другие способы определения языка данного элемента при тестировании псевдокласса :lang(), который может быть определен языком документа и/или реализацией, тогда как селектор атрибута будет только< /em> проверить элемент на наличие данного атрибута без какой-либо сопутствующей семантики на основе документа.

Например, в HTML псевдокласс также будет соответствовать любому потомку элемента, для которого нет другого lang, в зависимости от того, как браузер определяет язык для этих потомков. Обычно потомки наследуют атрибут языка от своего предка, если он не установлен явно.

Вот что говорится в спецификации:

Разница между :lang(C) и оператором «|=» заключается в том, что оператор «|=» выполняет сравнение только с заданным атрибутом элемента, в то время как псевдокласс :lang(C) использует знания UA о семантике документа для выполнения сравнения.

В этом примере HTML только BODY соответствует [lang|=fr] (поскольку у него есть атрибут LANG), но и BODY, и P соответствуют :lang(fr) (поскольку оба они на французском языке). P не соответствует [lang|=fr], потому что у него нет атрибута LANG.

<body lang=fr>
  <p>Je suis français.</p>
</body>

Обратите внимание на конкретные формулировки «имеет атрибут LANG» и «на французском языке». Эти две фразы имеют очень разные значения в английском языке, как вы можете себе представить.

В вашем примере следующий селектор также будет соответствовать вашему элементу .foo:

.foo:lang(en)

Но следующие селекторы не будут работать, если для них не установлен собственный атрибут lang:

.foo[lang="en"]
.foo[lang|="en"]

Что касается поддержки браузеров, псевдокласс :lang() поддерживается, начиная с IE8, поэтому IE7 действительно является единственным браузером, который вы не сможете поддерживать, используя псевдокласс вместо селектора атрибутов.

Основываясь на этом понимании, вы можете затем ответить на вопрос «что мне следует использовать»: вы должны всегда использовать псевдокласс :lang() по умолчанию, если только некоторые особенности (или необходимость поддержки IE7) не требуют обходного пути. вместо этого используйте селектор атрибутов.


Селекторы 4 не только привносят в псевдокласс :lang() расширенную функциональность ( тем самым увеличивая разрыв в функциональности между ним и селекторами атрибутов), но также вводит :dir() псевдокласс для сопоставления элементов на основе их направленности. Поскольку направленность является свойством, связанным с языком, атрибуты dir и lang в HTML работают одинаково, а разница между :dir() и соответствующим ему селектором атрибутов аналогична разнице между :lang() и соответствующим ему селектором атрибутов — до точки, где первое предложение следующая цитата на самом деле является дословной копией того же абзаца в разделе, описывающем :lang():

Разница между :dir(C) и ''[dir=C]'' заключается в том, что ''[dir=C]'' выполняет сравнение только с заданным атрибутом элемента, в то время как :dir(C) псевдо- class использует знания UA о семантике документа для выполнения сравнения. Например, в HTML направление элемента наследуется, так что дочерний элемент без атрибута dir будет иметь ту же направленность, что и его ближайший предок с допустимым атрибутом dir. В качестве другого примера, в HTML элемент, который соответствует ''[dir=auto]'', будет соответствовать либо :dir(ltr), либо :dir(rtl) в зависимости от разрешенной направленности элементов, определяемой его содержимым. [HTML5]

person BoltClock    schedule 18.01.2012
comment
Является ли атрибут xml:lang невидимым для веб-браузера (поскольку веб-браузер является парсером HTML, а не парсером XML)? Я пытался использовать селекторы, перечисленные в этой статье w3. через пользовательский CSS, но они не работают на этой веб-странице. Элемент <html> на этой японской веб-странице указывает только атрибут xml:lang, а не атрибут lang. - person 3 to 5 business days; 16.08.2014
comment
@ 3to5businessdays: Да, хотя я должен отметить, что современные браузеры на самом деле имеют парсеры HTML и XML - какой из них используется, определяется типом контента, заданным сервером. В любом случае, если элемент <html> содержит только атрибут xml:lang, а не атрибут lang, то он недействителен. Это связано с тем, что в HTML применяется только атрибут lang, и именно по этой причине псевдо :lang() не соответствует. - person BoltClock; 16.08.2014
comment
Я случайно проголосовал против, не могли бы вы внести тривиальное изменение, чтобы я мог удалить голосование? - person Florian; 06.06.2017
comment
@ Флориан: Готово. - person BoltClock; 06.06.2017

Еще одна вещь, о которой не упоминал никто другой - псевдокласс :lang() не интересует, как задается язык элемента. В документе XHTML (настоящий XHTML с типом XML MIME) вы можете использовать xml:lang="en", и элемент будет соответствовать :lang(en), но не [lang="en"].

person duri    schedule 18.01.2012
comment
Вернее, спецификация упоминает об этом. - person BoltClock; 19.01.2012

Согласно спецификации,

Если язык документа указывает, как определяется человеческий язык элемента, можно написать селекторы в CSS, которые соответствуют элементу на основе его языка. Например, в HTML [HTML4] язык определяется комбинацией атрибута lang, элемента META и, возможно, информацией из протокола (такой как заголовки HTTP). XML использует атрибут с именем xml:lang, и могут быть другие методы определения языка документа, зависящие от языка.

Псевдокласс ':lang(C)' соответствует, если элемент находится на языке C. Наличие совпадения основано исключительно на том, что идентификатор C либо равен языковому значению элемента, либо разделенной дефисом подстроке, так же, как если бы выполнялся оператор '|='. Сопоставление C со значением языка элемента выполняется без учета регистра для символов в диапазоне ASCII. Идентификатор C не обязательно должен быть допустимым названием языка.

То есть:

  1. It works for the many other ways of specifying a language besides the simple lang attribute.
    • Most importantly, as detailed in @BoltClock's answer, it will use the language specified (in whatever manner) on a container element, not just on the element itself, since language is inherited by child elements.
  2. Он использует семантику |=, то есть :lang(en) и :lang(us) будут соответствовать span[lang=en-us].
  3. Он гарантированно нечувствителен к регистру, тогда как

Чувствительность к регистру имен атрибутов и значений в селекторах зависит от языка документа.

person Domenic    schedule 18.01.2012

Css поддерживает селекторы атрибутов для всех элементов, а не только для атрибута html tags lang. Например, html типа <a title="Jeeha" href="foo.html">bar</a> можно выбрать как a[title=Jeeha] { ... } в css.

См. эту ссылку для получения более подробной информации о частичных совпадениях и вариантах.

person kontur    schedule 18.01.2012