是否可以定位没有语言设置或继承的元素,即使用未指定(“未知”)语言的元素?
\nHTML 文档或元素语言可以使用HTMLlang属性设置,例如:
<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>\nRun Code Online (Sandbox Code Playgroud)\nHTTP或在内容语言标头中使用代码:
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]\nRun Code Online (Sandbox Code Playgroud)\n或者它早已被弃用但仍然有效<meta http-equiv>:
<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]\nRun Code Online (Sandbox Code Playgroud)\n在任何一种情况下,使用:lang(en)CSS 选择器都会匹配示例中的主标题以及所有其他没有lang值不等于或以“en”开头的显式属性的元素。
如果发送的文档没有 Content-languageHTTP 标头或<meta>元素且没有 lang属性,是否可以匹配那些不可避免的“未知”语言的元素?
另外,在通过任何上述方式设置语言的文档或 DOM 片段中,是否可以使用lang()CSS 选择器来匹配具有空属性的lang=""元素,从而有效地“选择退出”语言?
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>\nRun Code Online (Sandbox Code Playgroud)\n:lang()、:lang(unknown)、:lang(\'\')和 都不能:not(:lang(*))用于此目的。派生的选择器:not([lang]), [lang=\'\']在逻辑上会对存在 HTTP 内容语言标头/元的用例给出假阴性。
寻求答案,要么给出没有漏报的解决方案,要么通过参考规范(或它们的缺失)来确认这是不可能的,并解释为什么会这样。
\n当存在空lang=""属性时,使用[lang=""]属性选择器定位它是可行的,但考虑到有专门的:lang()伪类用于与语言相关的东西,感觉很奇怪。
2021 年编辑:这已被视为错误https://bugs.chromium.org/p/chromium/issues/detail?id=1281157
\n我们在:lang()规则中提供语言范围,并将它们与语言标签进行匹配。他们提到了支持语言范围内的星号:
\n\n例如,包含星号的语言范围必须正确转义或引用为字符串,例如 :lang(*-Latn) 或 :lang("*-Latn") ref
\n
在旧的 2013 年草案中:
\n\n\n:lang() 中的每个语言范围必须是有效的 CSS 标识符 [CSS21] 或由星号 (* U+002A) 和紧跟以 ASCII 连字符 (U+002D) 开头的标识符组成,选择器才有效。参考
\n
但我无法p:lang(\\*-US)在 Windows 上使用 Chrome 和 Firefox。该规则p:lang(en\\002DUS)在思想上有效,但p:lang(en\\002D\\002A) 则不然。不确定special range "*"浏览器中的支持状态。在语言标签的匹配中也没有提到undefined通过特殊范围“*”进行匹配。
但是,p:lang(\\*)并且p:not(:lang(\\*))可以在 iPadO 上使用 Safari 和 Chrome。在 ipad 上打开这个jsfiddle
\n
\n
我认为 chromium 不\xe2\x80\x99t 支持全部:lang()功能。
解决方法:如果可以接受一点 JavaScript,那么您可以尝试以下解决方案:
\ndocument.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\np {\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
在这里,我们使用 JavaScript 来确定 html 标记或响应标头中是否提到了该语言。并指定 html 标签dummyLang语言。您可能还想检查元标记。
\n有关在 javascript 中获取 HTTP 标头以及此技术的优缺点的详细说明,请参阅此SO 讨论。