CSS :lang() 选择器用于未确定语言的文档中的元素

myf*_*myf 5 css

是否可以定位没有语言设置或继承的元素,即使用未指定(“未知”)语言的元素?

\n

琐事

\n

HTML 文档或元素语言可以使用HTMLlang属性设置,例如:

\n
<html lang="en">\n<h1>Dictionary</h1>\n<dl>\n<dt><abbr lang="en-Mors">-... - .--</abbr>\n<dd><i lang="fr-Latn">\xc3\xa0 propos</i>\n</dl>\n
Run Code Online (Sandbox Code Playgroud)\n

HTTP或在内容语言标头中使用代码:

\n
HTTP/2 200 OK\n[other headers]\nContent-language: en,en-Brai,fr-Latn\n\n<html>\n<h1>Dictionary</h1>\n[rest of document]\n
Run Code Online (Sandbox Code Playgroud)\n

或者它早已被弃用但仍然有效<meta http-equiv>

\n
<html>\n <head>\n  <meta http-equiv="content-language" content="en,en-Brai,fr-Latn">\n</head>\n<html>\n<h1>Dictionary</h1>\n[rest of document]\n
Run Code Online (Sandbox Code Playgroud)\n

在任何一种情况下,使用:lang(en)CSS 选择器都会匹配示例中的主标题以及所有其他没有lang值不等于或以“en”开头的显式属性的元素。

\n

目标

\n

如果发送的文档没有 Content-languageHTTP 标头或<meta>元素且没有 lang属性,是否可以匹配那些不可避免的“未知”语言的元素?

\n

另外,在通过任何上述方式设置语言的文档或 DOM 片段中,是否可以使用lang()CSS 选择器来匹配具有空属性的lang=""元素,从而有效地“选择退出”语言?

\n
HTTP/2 200 OK\n[no content-language header nor meta present]\n\n<html>\n<p>I Want to select this. <span>And this.</span></p>\n<p lang="">And this.</p>\n<p lang="en">Not this. <span lang="">But this again.</span></p>\n
Run Code Online (Sandbox Code Playgroud)\n

什么不起作用

\n

:lang():lang(unknown):lang(\'\')和 都不能:not(:lang(*))用于此目的。派生的选择器:not([lang]), [lang=\'\']在逻辑上会对存在 HTTP 内容语言标头/元的用例给出假阴性。

\n

回答要求

\n

寻求答案,要么给出没有漏报的解决方案,要么通过参考规范(或它们的缺失)来确认这是不可能的,并解释为什么会这样。

\n
\n

笔记:

\n

当存在空lang=""属性时,使用[lang=""]属性选择器定位它是可行的,但考虑到有专门的:lang()伪类用于与语言相关的东西,感觉很奇怪。

\n

onk*_*kar 3

2021 年编辑:这已被视为错误https://bugs.chromium.org/p/chromium/issues/detail?id=1281157

\n
\n

我们在:lang()规则中提供语言范围,并将它们与语言标签进行匹配。他们提到了支持语言范围内的星号:

\n
\n

例如,包含星号的语言范围必须正确转义或引用为字符串,例如 :lang(*-Latn) 或 :lang("*-Latn") ref

\n
\n

在旧的 2013 年草案中:

\n
\n

:lang() 中的每个语言范围必须是有效的 CSS 标识符 [CSS21] 或由星号 (* U+002A) 和紧跟以 ASCII 连字符 (U+002D) 开头的标识符组成,选择器才有效。参考

\n
\n

但我无法p:lang(\\*-US)在 Windows 上使用 Chrome 和 Firefox。该规则p:lang(en\\002DUS)在思想上有效,但p:lang(en\\002D\\002A) 则不然。不确定special range "*"浏览器中的支持状态。在语言标签的匹配中也没有提到undefined通过特殊范围“*”进行匹配。

\n


但是,p:lang(\\*)并且p:not(:lang(\\*))可以在 iPadO 上使用 Safari 和 Chrome。在 ipad 上打开这个jsfiddle
\n工作在IOS\n
我认为 chromium 不\xe2\x80\x99t 支持全部:lang()功能。

\n
\n

解决方法:如果可以接受一点 JavaScript,那么您可以尝试以下解决方案:

\n

\r\n
\r\n
document.addEventListener(\'DOMContentLoaded\', init);\n\nfunction init() {\n  if (!document.documentElement.lang) {\n    fetchSamePageHeaders(checkHeaderLanguage);\n  }\n}\n\n//make a lightweight request to the same page to get headers\nfunction fetchSamePageHeaders(callback) {\n  var request = new XMLHttpRequest();\n  request.onreadystatechange = function() {\n    if (request.readyState === XMLHttpRequest.DONE) {\n      if (callback && typeof callback === \'function\') {\n        callback(request.getAllResponseHeaders());\n      }\n    }\n  };\n\n  // The HEAD method asks for a response identical to that \n  // of a GET request, but without the response body.\n  //you can also use \'GET\', \'POST\' method depending on situation      \n  request.open(\'HEAD\', document.location, true);\n  request.send(null);\n}\n\nfunction checkHeaderLanguage(headers) {\n  //console.log(headers);\n  headers = headers.split("\\n").map(x => x.split(/: */, 2))\n    .filter(x => x[0]).reduce((ac, x) => {\n      ac[x[0]] = x[1];\n      return ac;\n    }, {});\n\n  if (!headers[\'content-language\']) {\n    console.log(\'No language in response header. Marking the html tag.\');\n    let html = document.querySelector(\'html\');\n    html.lang = \'dummyLang\';\n  } else {\n    console.log(\'The response header has language:\' + headers[\'content-language\']);\n  }\n}
Run Code Online (Sandbox Code Playgroud)\r\n
p {\n  margin: 0;\n}\n\np[lang=""],\np:lang(dummyLang) {\n  color: darkgreen;\n  font-size: 2em;\n}\n\np:lang(en\\2dus)::after {\n  content: \'<= english\';\n  font-size: 0.5em;\n  color: rebeccapurple;\n}
Run Code Online (Sandbox Code Playgroud)\r\n
<p>I Want to select this.</p>\n<p lang="">And this.</p>\n<p lang="en-us">Not this.</p>\n<span lang=\'en-us\'>\n    <p>Also, not this.</p>\n    <p lang="">But, this too.</p>\n</span>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n


在这里,我们使用 JavaScript 来确定 html 标记或响应标头中是否提到了该语言。并指定 html 标签dummyLang语言。您可能还想检查元标记。
\n有关在 javascript 中获取 HTTP 标头以及此技术的优缺点的详细说明,请参阅此SO 讨论

\n