quotes属性必须配合content: open-quote才生效,且需同时设置quotes、::before和::after伪元素;中文引号需:lang(zh)匹配与lang="zh"声明;嵌套引号依赖偶数字符串对;移动端推荐Unicode字符并避免运行时切语言依赖quotes。

quotes属性必须配合content: open-quote才生效
只写quotes: "“" "”",页面上<q>你好</q>依然没引号。浏览器不会自动扫描文本里的字符,它只在伪元素里显式调用open-quote或close-quote时查表。
必须同时做两件事:
q { quotes: "“" "”"; }-
q::before { content: open-quote; }和q::after { content: close-quote; }
漏掉任一环节,引号就完全不出现。常见错误是写了quotes但忘了伪元素,或者写了content: "“"这种字面量——这绕过了语言适配机制,lang就失效了。
中文引号生效的前提是:lang(zh) + lang="zh"
quotes本身不识别语言,它只响应 CSS 中的:lang()选择器匹配。没配:lang(zh)规则,或 HTML 元素没带lang="zh",浏览器一律 fallback 到英文双引号。
立即学习“前端免费学习笔记(深入)”;
检查点:
-
<html lang="zh">是否写在根节点(推荐) - 或至少在语义元素上明确声明:
<q lang="zh">你好</q> - CSS 规则必须写成:
:lang(zh) q { quotes: "“" "”"; },不能只写q { quotes: ... }
用[lang="zh"]也能工作,但:lang(zh)支持子标签继承(比如lang="zh-Hans"也匹配),语义更准确、兼容性更好。
嵌套层级靠字符串对数决定,不是自动循环
quotes值必须是偶数个带引号的字符串,两两成对,空格分隔。顺序即嵌套深度:第一对用于最外层,第二对用于第一层内嵌,第三对用于再内嵌……超出定义范围的层级会 fallback 到 UA 默认引号(不是重复用最后一对)。
例如:
-
quotes: "「" "」" "『" "』";→ 外层用「」,内嵌用『』 -
quotes: "“" "”";→ 只定义一对,第二层起用浏览器默认(通常是英文双引号) -
quotes: "“" "”" "‘";→ 奇数个 → 整条声明被忽略
中文排版极少需要三层以上嵌套,建议只设一对,避免意外触发英文单引号。
移动端和动态切语言时别依赖quotes
Android 某些版本对 HTML 实体(如“)渲染异常,推荐直接用 Unicode 字符"“"和"”";CSS 文件编码需为 UTF-8,HTML 也得声明<meta charset="utf-8">。
如果页面支持运行时切换语言(比如顶部语言开关),quotes完全无法响应。因为:lang()只在 DOM 解析时匹配一次,JS 修改lang属性不会触发重匹配。
此时该换方案:
- 移除所有
:lang()相关quotes规则 - 用 class 控制:
.lang-zh q::before { content: "“"; } - JS 切换时只改
<html class="lang-zh">,不碰lang属性
最容易被忽略的一点:quotes 的作用域仅限于你显式调用open-quote的地方——它不管 HTML 文本里已有的引号字符,也不影响text内容。想统一管理,就得从伪元素入口控制。


















