lang="fr"必须直接写在法语内容的语义化容器(如、、)上,且仅支持标准bcp 47代码fr;混排时需分层标注,动态渲染须确保html片段自带lang属性。

lang="fr"必须写在法语内容的直接容器上
浏览器和屏幕阅读器(如 NVDA、VoiceOver)只识别 <td>、<code><p></p>、<th>、<code><blockquote></blockquote> 这类**语义化内容元素**上的 lang 属性,且仅作用于该元素及其子节点。给 <div> 或 <code><section></section> 加 lang="fr" 效果弱;给 <table> 或 <code><tr> 加则完全无效——这些标签本身不承载语言语义。
<p>常见错误现象:</p>
<ul>
<li>
<code><table lang="fr"><tr><td>bonjour</td></tr></table> → “bonjour”仍被读成中文音节
<div lang="fr"><p>Merci beaucoup</p></div> → 读屏软件可能忽略外层 div,只按 <p></p> 是否带 lang 判断正确做法是:法语文本出现在哪一层,就往那一层写 lang="fr"。
别用“fr_FR”或“french”,必须用标准BCP 47代码 fr
fr 是唯一被全平台稳定支持的法语语言代码。写成 fr_FR(虽符合BCP 47)在部分旧版 Safari 和某些 TTS 引擎中会降级为无语言识别;french、FR、fr-fr(小写+下划线)、fr_CH(瑞士法语)等均不被识别,浏览器静默忽略。
实操要点:
- 主页面是法语:根标签必须是
,不是 - 局部法语段落:
<p lang="fr">La programmation web est passionnante.</p> - 法语引文优先用语义化标签:
<blockquote lang="fr">…</blockquote>,比<div> 更可靠 <li>表格单元格里的法语词:<code><td lang="fr">interface utilisateur</td>,不能靠<tr> 继承 <h3>中法混排时,<code>lang不能“一刀切”一个
<td> 或 <code><p></p>里既有中文说明又有法语术语(如“调用useState钩子”),不能整个元素设lang="zh-CN"或lang="fr"—— 否则法语部分会被中文TTS硬读,或中文部分被法语引擎错切音节。解决方案是分层标注:
- 外层保持主语言:
<p lang="zh-CN"></p> - 法语技术词用
<code lang="fr">包裹:<code lang="fr">useState - 避免用
<span></span>或<div> 套法语词——它们无语义,多数读屏软件不触发语言切换 <li>若整句是法语但夹少量中文专有名词(如“React 的 <code>useEffect”),建议反向处理:<p lang="fr">L’effet de bord avec <code lang="en">useEffectdans React - 后端返回的法语 HTML 片段,必须自带
lang="fr"(如<p lang="fr">…</p>) - 前端 JS 拼接时,显式写入:
`<p lang="fr">${text}</p>` - 框架中用
v-html或dangerouslySetInnerHTML前,确保传入的字符串已含合法lang属性 - 千万别依赖“全局切换语言”逻辑来统一改
lang—— 它只影响新渲染节点,老内容依旧卡在旧语言上下文里
动态渲染法语内容时,
lang必须随 HTML 字符串一起注入用 JS 拼接字符串、React
dangerouslySetInnerHTML、Vuev-html渲染法语内容时,仅靠初始 HTML 写对lang不够。JS 后期执行el.setAttribute('lang', 'fr')或修改document.documentElement.lang,对已渲染的子节点无效——语音引擎不重载,CSS:lang(fr)不重匹配,翻译按钮不刷新。关键动作:
最易被忽略的一点:法语中的标点(如 « guillemets »)和空格规则依赖
lang="fr"触发字体回退链,漏设会导致引号显示为英文双引号、间距异常,甚至文字糊在一起。这不是样式问题,是语言标记缺失的底层表现。 - 外层保持主语言:











