# 网页的隐藏维度:国际化与无障碍
::: tip 核心导读
**什么是 i18n 及其来龙去脉?**
在前端和软件工程领域,我们常说的 **i18n** 其实就是指 **多语言支持(国际化,Internationalization)**。因为这个英文单词的首字母 `i` 和尾字母 `n` 之间恰好相隔了 18 个字母,为了书写简便,业界便发明了这个特定的缩写。
同理,**无障碍访问(Accessibility)** 也因为首字母 `a` 与尾字母 `y` 之间有 11 个字母,因此被统称为 **a11y**。
在浏览器将代码渲染出五彩斑斓的网页背后,其实还并行着两条肉眼往往看不见的“暗线”:
当你输入网址访问网页时,浏览器怎么知道该给你展示中文还是德文(即 i18n 多语言流程)?在浏览器将 HTML 解析成 DOM 树准备画图的同时,又是如何专门为视障人士构建出另一棵“盲文树”的(即 a11y 无障碍流程)?
本章我们将再次回到“网页访问与渲染”的微观流程中,解码浏览器及前端工程在这两个体现技术人文关怀的领域是如何默默工作的。
:::
---
## 1. 网页访问中的语言协商 (i18n)
当我们输入一个网址、按下回车,浏览器在向服务器发送 HTTP 请求时,通常会默默附带一个头信息:`Accept-Language`。
- *例如:`Accept-Language: zh-CN,zh;q=0.9,en;q=0.8`*
这就好比你在餐厅点单前,浏览器私下对服务员说:“我的主人优先看简体中文,如果没有的话,英文也凑合能看。” 这就是 Web 访问时的**初次协商**。
### 1.1 前端工程与字典替换
而在现代前端框架中,页面的骨架通常是由 JavaScript 在本地动态生成的。在这个阶段,前端应用会主动读取浏览器的本地偏好(例如通过 `navigator.language` API),然后从服务器按需拉取对应的语言“字典包(JSON)”——遇到中文显示“确定”,遇到英文字典则显示“Confirm”。
### 1.2 排版的深渊:文字长度与 RTL 镜像
但除了字典替换,真正的国际化在浏览器布局(Layout)阶段面临着深渊般的挑战。
不同的语言表达相同的含义时,所需的字母长度可能天差地别。例如德语常将多个词根拼接成巨长的单词。如果我们在编写 CSS 时使用绝对固定宽度,很容易在切换德语时出现文字撑破容器的惨状。因此浏览器鼓励使用弹性盒模型(Flexbox)来自适应不同的文字体量。
更为颠覆的挑战在于阅读方向。阿拉伯语(Arabic)、希伯来语(Hebrew)等语言的阅读习惯是**从右向左(Right-to-Left, 简称 RTL)**。
当页面切换到这类语言时,不仅仅是文本方向要变,**浏览器引擎还需要对整个网页的内容块进行水平方向的镜像反转**!浏览器为此提供了原生的 `dir="rtl"` 属性。我们在编写 CSS 时,应当避免使用绝对的方向词,例如用 Flexbox 的 `justify-content: flex-start` 来替代硬编码的 `margin-left`,从而让浏览器能够随着区域切换自动化反转布局。
### 1.3 告别正则:拥抱浏览器的 Intl 标准
除了界面排版,浏览器底层还自带了一个强大的“本地化格式引擎”。
对于同样的数字 `1200.5`,美国人习惯看到 `$1,200.50`,而欧洲许多国家习惯用逗号做小数点 `€ 1.200,50`。日期格式更是千奇百怪。
现代浏览器暴露了 **`Intl` 核心对象**(例如 `Intl.DateTimeFormat` 和 `Intl.NumberFormat`)。依靠这个 API,我们在代码里只要指明当前环境代号,浏览器便会直接调用底层的操作系统数据规范,准确生成符合当地习惯的展示字符串。
👇 操作下方组件,观察在不改变源数据的前提下,浏览器是如何通过底层 API 完成布局反转(RTL)与系统级数据转换的: